diff --git a/src/arch/zx48k/backend/__init__.py b/src/arch/zx48k/backend/__init__.py index f36248bb5..cc37d5003 100644 --- a/src/arch/zx48k/backend/__init__.py +++ b/src/arch/zx48k/backend/__init__.py @@ -14,6 +14,8 @@ from . import errors from .errors import InvalidICError as InvalidIC +from .runtime.namespace import NAMESPACE + # 8 bit arithmetic functions from .__8bit import _add8, _sub8, _mul8, _divu8, _divi8, _modu8, _modi8, _neg8, _abs8 @@ -116,12 +118,12 @@ RE_IX_IDX = re.compile(r'^\([ \t]*ix[ \t]*[-+][ \t]*.+\)$') # Label for the program START end EXIT -START_LABEL = '__START_PROGRAM' -END_LABEL = '__END_PROGRAM' -CALL_BACK = '__CALL_BACK__' -MAIN_LABEL = '__MAIN_PROGRAM__' -DATA_LABEL = 'ZXBASIC_USER_DATA' -DATA_END_LABEL = 'ZXBASIC_USER_DATA_END' +START_LABEL = f'{NAMESPACE}__START_PROGRAM' +END_LABEL = f'{NAMESPACE}__END_PROGRAM' +CALL_BACK = f'{NAMESPACE}__CALL_BACK__' +MAIN_LABEL = f'{NAMESPACE}__MAIN_PROGRAM__' +DATA_LABEL = f'{NAMESPACE}ZXBASIC_USER_DATA' +DATA_END_LABEL = f'{NAMESPACE}ZXBASIC_USER_DATA_END' # Whether to use the FunctionExit scheme FLAG_use_function_exit = False @@ -196,9 +198,9 @@ def init(): # Default HEAP SIZE (Dynamic memory) in bytes OPTIONS.add_option('heap_size', int, 4768) # A bit more than 4K # Labels for HEAP START (might not be used if not needed) - OPTIONS.add_option('heap_start_label', str, f'{RuntimeLabel.NAMESPACE}ZXBASIC_MEM_HEAP') + OPTIONS.add_option('heap_start_label', str, f'{NAMESPACE}ZXBASIC_MEM_HEAP') # Labels for HEAP SIZE (might not be used if not needed) - OPTIONS.add_option('heap_size_label', str, f'{RuntimeLabel.NAMESPACE}ZXBASIC_HEAP_SIZE') + OPTIONS.add_option('heap_size_label', str, f'{NAMESPACE}ZXBASIC_HEAP_SIZE') # Flag for headerless mode (No prologue / epilogue) OPTIONS.add_option('headerless', bool, False) @@ -2222,16 +2224,16 @@ def emit_start(): heap_init = ['%s:' % DATA_LABEL] output.append('org %s' % OPTIONS.org) - if REQUIRES.intersection(MEMINITS) or '__MEM_INIT' in INITS: + if REQUIRES.intersection(MEMINITS) or f'{NAMESPACE}__MEM_INIT' in INITS: heap_init.append('; Defines HEAP SIZE\n' + OPTIONS.heap_size_label + ' EQU ' + str(OPTIONS.heap_size)) heap_init.append(OPTIONS.heap_start_label + ':') heap_init.append('DEFS %s' % str(OPTIONS.heap_size)) heap_init.append('; Defines USER DATA Length in bytes\n' + - 'ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA') - heap_init.append('.__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN') - heap_init.append('.__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA') + f'{NAMESPACE}ZXBASIC_USER_DATA_LEN EQU {DATA_END_LABEL} - {DATA_LABEL}') + heap_init.append(f'{NAMESPACE}.__LABEL__.ZXBASIC_USER_DATA_LEN EQU {NAMESPACE}ZXBASIC_USER_DATA_LEN') + heap_init.append(f'{NAMESPACE}.__LABEL__.ZXBASIC_USER_DATA EQU {DATA_LABEL}') output.append('%s:' % START_LABEL) if OPTIONS.headerless: diff --git a/src/arch/zx48k/backend/runtime/namespace.py b/src/arch/zx48k/backend/runtime/namespace.py index 9f4973818..e17cf8fde 100644 --- a/src/arch/zx48k/backend/runtime/namespace.py +++ b/src/arch/zx48k/backend/runtime/namespace.py @@ -1,3 +1,3 @@ # Define just the main Private namespace -NAMESPACE = '' +NAMESPACE = 'core.' diff --git a/src/arch/zx48k/library-asm/SP/CharLeft.asm b/src/arch/zx48k/library-asm/SP/CharLeft.asm index 9b01b8318..641754bfa 100644 --- a/src/arch/zx48k/library-asm/SP/CharLeft.asm +++ b/src/arch/zx48k/library-asm/SP/CharLeft.asm @@ -1,54 +1,59 @@ -; -; CharLeft -; Alvin Albrecht 2002 -; - -;INCLUDE "SPconfig.def" -;XLIB SPCharLeft - -; Char Left -; -; Adjusts screen address HL to move one character to the left -; on the display. Start of line wraps to the previous row. -; -; enter: HL = valid screen address -; Carry reset -; exit : Carry = moved off screen -; HL = moves one character left, with line wrap -; used : AF, HL - -;IF !DISP_HIRES - -SP.CharLeft: - ld a,l - dec l - or a - ret nz - ld a,h - sub $08 - ld h,a - cp $40 - ret - -;ELSE - -;.SPCharLeft -; ld a,h -; xor $20 -; ld h,a -; cp $58 -; ccf -; ret nc -; ld a,l -; dec l -; or a -; ret nz -; ld a,h -; sub $08 -; ld h,a -; and $18 -; cp $18 -; ccf -; ret - -; ENDIF +; +; CharLeft +; Alvin Albrecht 2002 +; + +;INCLUDE "SPconfig.def" +;XLIB SPCharLeft + +; Char Left +; +; Adjusts screen address HL to move one character to the left +; on the display. Start of line wraps to the previous row. +; +; enter: HL = valid screen address +; Carry reset +; exit : Carry = moved off screen +; HL = moves one character left, with line wrap +; used : AF, HL + +;IF !DISP_HIRES + + push namespace core + +SP.CharLeft: + ld a,l + dec l + or a + ret nz + ld a,h + sub $08 + ld h,a + cp $40 + ret + + pop namespace + + +;ELSE + +;.SPCharLeft +; ld a,h +; xor $20 +; ld h,a +; cp $58 +; ccf +; ret nc +; ld a,l +; dec l +; or a +; ret nz +; ld a,h +; sub $08 +; ld h,a +; and $18 +; cp $18 +; ccf +; ret + +; ENDIF \ No newline at end of file diff --git a/src/arch/zx48k/library-asm/SP/CharRight.asm b/src/arch/zx48k/library-asm/SP/CharRight.asm index 14ad383b8..1a47d84cb 100644 --- a/src/arch/zx48k/library-asm/SP/CharRight.asm +++ b/src/arch/zx48k/library-asm/SP/CharRight.asm @@ -1,49 +1,54 @@ -; -; CharRight -; Alvin Albrecht 2002 -; - -;INCLUDE "SPconfig.def" -;XLIB SPCharRight - -; Char Right -; -; Adjusts screen address HL to move one character to the right -; on the display. End of line wraps to the next row. -; -; enter: HL = valid screen address -; Carry reset -; exit : Carry = moved off screen -; HL = moves one character right, with line wrap -; used : AF, HL - -;IF !DISP_HIRES - -SP.CharRight: - inc l - ret nz - ld a,8 - add a,h - ld h,a - cp $58 - ccf - ret - -;ELSE - -;.SPCharRight -; ld a,h -; xor $20 -; ld h,a -; cp $58 -; ret nc -; inc l -; ret nz -; ld a,8 -; add a,h -; ld h,a -; cp $58 -; ccf -; ret - -; ENDIF +; +; CharRight +; Alvin Albrecht 2002 +; + +;INCLUDE "SPconfig.def" +;XLIB SPCharRight + +; Char Right +; +; Adjusts screen address HL to move one character to the right +; on the display. End of line wraps to the next row. +; +; enter: HL = valid screen address +; Carry reset +; exit : Carry = moved off screen +; HL = moves one character right, with line wrap +; used : AF, HL + +;IF !DISP_HIRES + + push namespace core + +SP.CharRight: + inc l + ret nz + ld a,8 + add a,h + ld h,a + cp $58 + ccf + ret + + pop namespace + + +;ELSE + +;.SPCharRight +; ld a,h +; xor $20 +; ld h,a +; cp $58 +; ret nc +; inc l +; ret nz +; ld a,8 +; add a,h +; ld h,a +; cp $58 +; ccf +; ret + +; ENDIF \ No newline at end of file diff --git a/src/arch/zx48k/library-asm/SP/GetScrnAddr.asm b/src/arch/zx48k/library-asm/SP/GetScrnAddr.asm index d50c34ac9..d238a424d 100644 --- a/src/arch/zx48k/library-asm/SP/GetScrnAddr.asm +++ b/src/arch/zx48k/library-asm/SP/GetScrnAddr.asm @@ -1,105 +1,110 @@ -; -; GetScrnAddr -; Alvin Albrecht 2002 -; - -;INCLUDE "SPconfig.def" -;XLIB SPGetScrnAddr - -; Get Screen Address -; -; Computes the screen address given a valid pixel coordinate. -; (0,0) is located at the top left corner of the screen. -; -; enter: a = h = y coord -; l = x coord -; In hi-res mode, Carry is most significant bit of x coord (0..511 pixels) -; exit : de = screen address, b = pixel mask -; uses : af, b, de, hl - -;IF !DISP_HIRES - -SPGetScrnAddr: - and $07 - or $40 - ld d,a - ld a,h - rra - rra - rra - and $18 - or d - ld d,a - - ld a,l - and $07 - ld b,a - ld a,$80 - jr z, norotate - -rotloop: - rra - djnz rotloop - -norotate: - ld b,a - srl l - srl l - srl l - ld a,h - rla - rla - and $e0 - or l - ld e,a - ret - -;ELSE -; -;.SPGetScrnAddr -; ld b,0 -; ld d,b -; rr l -; rl b -; srl l -; rl b -; srl l -; rl b -; srl l -; jr nc, notodd -; ld d,$20 -; -;.notodd -; ld a,b -; or a -; ld a,$80 -; jr z, norotate -; -;.rotloop -; rra -; djnz rotloop - -;.norotate -; ld b,a -; ld a,h -; and $07 -; or $40 -; or d -; ld d,a -; ld a,h -; rra -; rra -; rra -; and $18 -; or d -; ld d,a -; -; ld a,h -; rla -; rla -; and $e0 - ; or l -; ld e,a -; ret - -;ENDIF +; +; GetScrnAddr +; Alvin Albrecht 2002 +; + +;INCLUDE "SPconfig.def" +;XLIB SPGetScrnAddr + +; Get Screen Address +; +; Computes the screen address given a valid pixel coordinate. +; (0,0) is located at the top left corner of the screen. +; +; enter: a = h = y coord +; l = x coord +; In hi-res mode, Carry is most significant bit of x coord (0..511 pixels) +; exit : de = screen address, b = pixel mask +; uses : af, b, de, hl + +;IF !DISP_HIRES + + push namespace core + +SPGetScrnAddr: + and $07 + or $40 + ld d,a + ld a,h + rra + rra + rra + and $18 + or d + ld d,a + + ld a,l + and $07 + ld b,a + ld a,$80 + jr z, norotate + +rotloop: + rra + djnz rotloop + +norotate: + ld b,a + srl l + srl l + srl l + ld a,h + rla + rla + and $e0 + or l + ld e,a + ret + + pop namespace + + +;ELSE +; +;.SPGetScrnAddr +; ld b,0 +; ld d,b +; rr l +; rl b +; srl l +; rl b +; srl l +; rl b +; srl l +; jr nc, notodd +; ld d,$20 +; +;.notodd +; ld a,b +; or a +; ld a,$80 +; jr z, norotate +; +;.rotloop +; rra +; djnz rotloop + +;.norotate +; ld b,a +; ld a,h +; and $07 +; or $40 +; or d +; ld d,a +; ld a,h +; rra +; rra +; rra +; and $18 +; or d +; ld d,a +; +; ld a,h +; rla +; rla +; and $e0 + ; or l +; ld e,a +; ret + +;ENDIF \ No newline at end of file diff --git a/src/arch/zx48k/library-asm/SP/PixelDown.asm b/src/arch/zx48k/library-asm/SP/PixelDown.asm index fcc0abc18..1b8522d08 100644 --- a/src/arch/zx48k/library-asm/SP/PixelDown.asm +++ b/src/arch/zx48k/library-asm/SP/PixelDown.asm @@ -1,42 +1,46 @@ -; -; PixelDown -; Alvin Albrecht 2002 -; - -; Pixel Down -; -; Adjusts screen address HL to move one pixel down in the display. -; (0,0) is located at the top left corner of the screen. -; -; enter: HL = valid screen address -; exit : Carry = moved off screen -; Carry'= moved off current cell (needs ATTR update) -; HL = moves one pixel down -; used : AF, HL - -SP.PixelDown: - inc h - ld a,h - and $07 - ret nz - ex af, af' ; Sets carry on F' - scf ; which flags ATTR must be updated - ex af, af' - ld a,h - sub $08 - ld h,a - ld a,l - add a,$20 - ld l,a - ret nc - ld a,h - add a,$08 - ld h,a -;IF DISP_HIRES -; and $18 -; cp $18 -;ELSE - cp $58 -;ENDIF - ccf - ret +; +; PixelDown +; Alvin Albrecht 2002 +; + +; Pixel Down +; +; Adjusts screen address HL to move one pixel down in the display. +; (0,0) is located at the top left corner of the screen. +; +; enter: HL = valid screen address +; exit : Carry = moved off screen +; Carry'= moved off current cell (needs ATTR update) +; HL = moves one pixel down +; used : AF, HL + + push namespace core + +SP.PixelDown: + inc h + ld a,h + and $07 + ret nz + ex af, af' ; Sets carry on F' + scf ; which flags ATTR must be updated + ex af, af' + ld a,h + sub $08 + ld h,a + ld a,l + add a,$20 + ld l,a + ret nc + ld a,h + add a,$08 + ld h,a +;IF DISP_HIRES +; and $18 +; cp $18 +;ELSE + cp $58 +;ENDIF + ccf + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/SP/PixelLeft.asm b/src/arch/zx48k/library-asm/SP/PixelLeft.asm index 9081fbd6b..f8a97f8c5 100644 --- a/src/arch/zx48k/library-asm/SP/PixelLeft.asm +++ b/src/arch/zx48k/library-asm/SP/PixelLeft.asm @@ -1,31 +1,35 @@ -; -; PixelLeft -; Jose Rodriguez 2012 -; - -; PixelLeft -; -; Adjusts screen address HL and Pixel bit A to move one pixel to the left -; on the display. Start of line set Carry (Out of Screen) -; -; enter: HL = valid screen address -; A = Bit Set -; exit : Carry = moved off screen -; Carry' Set if moved off current ATTR CELL -; HL = moves one character left, if needed -; A = Bit Set with new pixel pos. -; used : AF, HL - - -SP.PixelLeft: - rlca ; Sets new pixel bit 1 to the right - ret nc - ex af, af' ; Signal in C' we've moved off current ATTR cell - ld a,l - dec a - ld l,a - cp 32 ; Carry if in screen - ccf - ld a, 1 - ret - +; +; PixelLeft +; Jose Rodriguez 2012 +; + +; PixelLeft +; +; Adjusts screen address HL and Pixel bit A to move one pixel to the left +; on the display. Start of line set Carry (Out of Screen) +; +; enter: HL = valid screen address +; A = Bit Set +; exit : Carry = moved off screen +; Carry' Set if moved off current ATTR CELL +; HL = moves one character left, if needed +; A = Bit Set with new pixel pos. +; used : AF, HL + + + push namespace core + +SP.PixelLeft: + rlca ; Sets new pixel bit 1 to the right + ret nc + ex af, af' ; Signal in C' we've moved off current ATTR cell + ld a,l + dec a + ld l,a + cp 32 ; Carry if in screen + ccf + ld a, 1 + ret + + pop namespace + diff --git a/src/arch/zx48k/library-asm/SP/PixelRight.asm b/src/arch/zx48k/library-asm/SP/PixelRight.asm index 3598c496c..c1e929619 100644 --- a/src/arch/zx48k/library-asm/SP/PixelRight.asm +++ b/src/arch/zx48k/library-asm/SP/PixelRight.asm @@ -1,32 +1,36 @@ -; -; PixelRight -; Jose Rodriguez 2012 -; - - -; PixelRight -; -; Adjusts screen address HL and Pixel bit A to move one pixel to the left -; on the display. Start of line set Carry (Out of Screen) -; -; enter: HL = valid screen address -; A = Bit Set -; exit : Carry = moved off screen -; Carry' Set if moved off current ATTR CELL -; HL = moves one character left, if needed -; A = Bit Set with new pixel pos. -; used : AF, HL - - -SP.PixelRight: - rrca ; Sets new pixel bit 1 to the right - ret nc - ex af, af' ; Signal in C' we've moved off current ATTR cell - ld a, l - inc a - ld l, a - cp 32 ; Carry if IN screen - ccf - ld a, 80h - ret - +; +; PixelRight +; Jose Rodriguez 2012 +; + + +; PixelRight +; +; Adjusts screen address HL and Pixel bit A to move one pixel to the left +; on the display. Start of line set Carry (Out of Screen) +; +; enter: HL = valid screen address +; A = Bit Set +; exit : Carry = moved off screen +; Carry' Set if moved off current ATTR CELL +; HL = moves one character left, if needed +; A = Bit Set with new pixel pos. +; used : AF, HL + + + push namespace core + +SP.PixelRight: + rrca ; Sets new pixel bit 1 to the right + ret nc + ex af, af' ; Signal in C' we've moved off current ATTR cell + ld a, l + inc a + ld l, a + cp 32 ; Carry if IN screen + ccf + ld a, 80h + ret + + pop namespace + diff --git a/src/arch/zx48k/library-asm/SP/PixelUp.asm b/src/arch/zx48k/library-asm/SP/PixelUp.asm index cebcadf8c..0e353eab2 100644 --- a/src/arch/zx48k/library-asm/SP/PixelUp.asm +++ b/src/arch/zx48k/library-asm/SP/PixelUp.asm @@ -1,41 +1,45 @@ -; -; PixelUp -; Alvin Albrecht 2002 -; - -; Pixel Up -; -; Adjusts screen address HL to move one pixel up in the display. -; (0,0) is located at the top left corner of the screen. -; -; enter: HL = valid screen address -; exit : Carry = moved off screen -; HL = moves one pixel up -; used : AF, HL - -SP.PixelUp: - ld a,h - dec h - and $07 - ret nz - ex af, af' - scf - ex af, af' - ld a,$08 - add a,h - ld h,a - ld a,l - sub $20 - ld l,a - ret nc - ld a,h - sub $08 - ld h,a -;IF DISP_HIRES -; and $18 -; cp $18 -; ccf -;ELSE - cp $40 -;ENDIF - ret +; +; PixelUp +; Alvin Albrecht 2002 +; + +; Pixel Up +; +; Adjusts screen address HL to move one pixel up in the display. +; (0,0) is located at the top left corner of the screen. +; +; enter: HL = valid screen address +; exit : Carry = moved off screen +; HL = moves one pixel up +; used : AF, HL + + push namespace core + +SP.PixelUp: + ld a,h + dec h + and $07 + ret nz + ex af, af' + scf + ex af, af' + ld a,$08 + add a,h + ld h,a + ld a,l + sub $20 + ld l,a + ret nc + ld a,h + sub $08 + ld h,a +;IF DISP_HIRES +; and $18 +; cp $18 +; ccf +;ELSE + cp $40 +;ENDIF + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/_mul32.asm b/src/arch/zx48k/library-asm/_mul32.asm index 2a5712edd..477e02a42 100644 --- a/src/arch/zx48k/library-asm/_mul32.asm +++ b/src/arch/zx48k/library-asm/_mul32.asm @@ -5,61 +5,65 @@ ; 64bit result is returned in H'L'H L B'C'A C + push namespace core + __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + + ret ; result in h'l'hlb'c'ac + + pop namespace - ret ; result in h'l'hlb'c'ac - diff --git a/src/arch/zx48k/library-asm/abs8.asm b/src/arch/zx48k/library-asm/abs8.asm index f23c4d109..499c8efa0 100644 --- a/src/arch/zx48k/library-asm/abs8.asm +++ b/src/arch/zx48k/library-asm/abs8.asm @@ -1,8 +1,12 @@ ; Returns absolute value for 8 bit signed integer ; + push namespace core + __ABS8: - or a - ret p - neg - ret + or a + ret p + neg + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/absf.asm b/src/arch/zx48k/library-asm/absf.asm index 0eac0bcc0..084e1d55f 100644 --- a/src/arch/zx48k/library-asm/absf.asm +++ b/src/arch/zx48k/library-asm/absf.asm @@ -1,4 +1,8 @@ ; ABS value for a floating point A EDCB + push namespace core + __ABSF: - res 7, e ; Sets sign to positive. Thast all! ;-) - ret + res 7, e ; Sets sign to positive. Thast all! ;-) + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/acos.asm b/src/arch/zx48k/library-asm/acos.asm index f39d70af2..b2030df2f 100644 --- a/src/arch/zx48k/library-asm/acos.asm +++ b/src/arch/zx48k/library-asm/acos.asm @@ -1,11 +1,15 @@ #include once + push namespace core + ACOS: ; Computes ACOS using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 23h ; ACOS + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 23h ; ACOS - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/addf.asm b/src/arch/zx48k/library-asm/addf.asm index 78b3ca538..50b02ab97 100644 --- a/src/arch/zx48k/library-asm/addf.asm +++ b/src/arch/zx48k/library-asm/addf.asm @@ -9,13 +9,17 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __ADDF: ; Addition - call __FPSTACK_PUSH2 - - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC + call __FPSTACK_PUSH2 + + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/alloc.asm b/src/arch/zx48k/library-asm/alloc.asm index de9b4840e..fde6d1df4 100644 --- a/src/arch/zx48k/library-asm/alloc.asm +++ b/src/arch/zx48k/library-asm/alloc.asm @@ -1,6 +1,6 @@ ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa -; (a.k.a. Boriel) +; (a.k.a. Boriel) ; http://www.boriel.com ; ; This ASM library is licensed under the MIT license @@ -13,20 +13,20 @@ ; The heap is implemented as a linked list of free blocks. ; Each free block contains this info: -; -; +----------------+ <-- HEAP START +; +; +----------------+ <-- HEAP START ; | Size (2 bytes) | ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK ; +----------------+ ; | Next (2 bytes) |---+ -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | <-- If Size > 4, then this contains (size - 4) bytes ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ @@ -35,14 +35,14 @@ ; | (0 if Size = 4)| | ; +----------------+ | ; | <-- This zone is in use (Already allocated) -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Next (2 bytes) |--> NULL => END OF LIST ; | 0 = NULL | ; +----------------+ @@ -59,7 +59,7 @@ ; MEMORY MANAGER ; -; This library must be initialized calling __MEM_INIT with +; This library must be initialized calling __MEM_INIT with ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. @@ -81,105 +81,109 @@ ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core + MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC + PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer - + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l + ld a, h ; HL = NULL (No memory available?) + or l #ifdef __MEMORY_CHECK__ - ld a, ERROR_OutOfMemory - jp z, __ERROR + ld a, ERROR_OutOfMemory + jp z, __ERROR #else - ret z ; NULL + ret z ; NULL #endif - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP - -__MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP + +__MEM_DONE: ; A free block has been found. + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer + ld hl, 0 ; Pre-previous block pointer + + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - - ret + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/and16.asm b/src/arch/zx48k/library-asm/and16.asm index a0ce0ccbe..f0f9e3dfd 100644 --- a/src/arch/zx48k/library-asm/and16.asm +++ b/src/arch/zx48k/library-asm/and16.asm @@ -3,12 +3,16 @@ ; __FASTCALL__ version (operands: DE, HL) ; Performs 16bit and 16bit and returns the boolean + push namespace core + __AND16: - ld a, h - or l - ret z + ld a, h + or l + ret z + + ld a, d + or e + ret - ld a, d - or e - ret + pop namespace diff --git a/src/arch/zx48k/library-asm/and32.asm b/src/arch/zx48k/library-asm/and32.asm index 76fa0329b..9723308a1 100644 --- a/src/arch/zx48k/library-asm/and32.asm +++ b/src/arch/zx48k/library-asm/and32.asm @@ -3,6 +3,8 @@ ; result in Accumulator (0 False, not 0 True) ; First operand in DE,HL 2nd operand into the stack + push namespace core + __AND32: ld a, l or h @@ -25,3 +27,5 @@ __AND32: #endif ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/and8.asm b/src/arch/zx48k/library-asm/and8.asm index 97b047608..c1e067c5a 100644 --- a/src/arch/zx48k/library-asm/and8.asm +++ b/src/arch/zx48k/library-asm/and8.asm @@ -3,9 +3,13 @@ ; __FASTCALL__ version (operands: A, H) ; Performs 8bit and 8bit and returns the boolean + push namespace core + __AND8: - or a - ret z - ld a, h - ret + or a + ret z + ld a, h + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/andf.asm b/src/arch/zx48k/library-asm/andf.asm index 4ecdd7a84..4a364f5cd 100644 --- a/src/arch/zx48k/library-asm/andf.asm +++ b/src/arch/zx48k/library-asm/andf.asm @@ -12,14 +12,18 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __ANDF: ; A & B - call __FPSTACK_PUSH2 + call __FPSTACK_PUSH2 + + ; ------------- ROM NO-&-NO + rst 28h + defb 08h ; + defb 38h; ; END CALC - ; ------------- ROM NO-&-NO - rst 28h - defb 08h ; - defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + pop namespace diff --git a/src/arch/zx48k/library-asm/array.asm b/src/arch/zx48k/library-asm/array.asm index ac2eba716..b9ca58313 100644 --- a/src/arch/zx48k/library-asm/array.asm +++ b/src/arch/zx48k/library-asm/array.asm @@ -1,6 +1,6 @@ ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa -; (a.k.a. Boriel) +; (a.k.a. Boriel) ; http://www.boriel.com ; ------------------------------------------------------------------- ; Simple array Index routine @@ -22,6 +22,8 @@ #include once #endif + push namespace core + __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl @@ -29,12 +31,12 @@ __ARRAY_PTR: ;; computes an array offset from a pointer ld l, c __ARRAY: - PROC + PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl @@ -42,24 +44,24 @@ __ARRAY: inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + + ld hl, 0 ; HL = Offset "accumulator" LOOP: #ifdef __CHECK_ARRAY_BOUNDARY__ pop de #endif - pop bc ; Get next index (Ai) from the stack + pop bc ; Get next index (Ai) from the stack #ifdef __CHECK_ARRAY_BOUNDARY__ ex de, hl @@ -70,32 +72,32 @@ LOOP: ex de, hl #endif - add hl, bc ; Adds current index + add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx + ld a, (hl) + exx #ifdef __BIG_ARRAY__ - ld d, 0 - ld e, a + ld d, 0 + ld e, a call __FNMUL #else LOCAL ARRAY_SIZE_LOOP @@ -110,15 +112,15 @@ ARRAY_SIZE_LOOP: #endif ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 @@ -144,5 +146,7 @@ __FNMUL2: TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP - + ENDP + + pop namespace + diff --git a/src/arch/zx48k/library-asm/arrayalloc.asm b/src/arch/zx48k/library-asm/arrayalloc.asm index 16077bca4..7ec636788 100644 --- a/src/arch/zx48k/library-asm/arrayalloc.asm +++ b/src/arch/zx48k/library-asm/arrayalloc.asm @@ -16,6 +16,8 @@ ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core + __ALLOC_LOCAL_ARRAY: push de push ix @@ -134,3 +136,5 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 #endif + + pop namespace diff --git a/src/arch/zx48k/library-asm/arraystrfree.asm b/src/arch/zx48k/library-asm/arraystrfree.asm index 60921fce8..e5555c524 100644 --- a/src/arch/zx48k/library-asm/arraystrfree.asm +++ b/src/arch/zx48k/library-asm/arraystrfree.asm @@ -4,57 +4,61 @@ #include once + push namespace core + __ARRAYSTR_FREE: - PROC + PROC + + LOCAL __ARRAY_LOOP - LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - - ex de, hl + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL + ld a, h + or l + ret z ; ret if NULL - ld b, d - ld c, e + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP - ret ; Frees it and return + ret ; Frees it and return - ENDP + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace diff --git a/src/arch/zx48k/library-asm/asc.asm b/src/arch/zx48k/library-asm/asc.asm index 6ee006250..e36962e9c 100644 --- a/src/arch/zx48k/library-asm/asc.asm +++ b/src/arch/zx48k/library-asm/asc.asm @@ -1,35 +1,39 @@ ; Returns the ascii code for the given str #include once + push namespace core + __ASC: - PROC - LOCAL __ASC_END - - ex af, af' ; Saves free_mem flag + PROC + LOCAL __ASC_END + + ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return + ld a, h + or l + ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) + ld c, (hl) + inc hl + ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return + ld a, b + or c + jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + inc hl + ld a, (hl) dec hl - + __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + + ex af, af' ; Recover result - ex af, af' ; Recover result + ret + ENDP - ret - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/asin.asm b/src/arch/zx48k/library-asm/asin.asm index 998d0d490..598bafb3d 100644 --- a/src/arch/zx48k/library-asm/asin.asm +++ b/src/arch/zx48k/library-asm/asin.asm @@ -1,11 +1,15 @@ #include once + push namespace core + ASIN: ; Computes ASIN using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 22h ; ASIN + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 22h ; ASIN - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/atan.asm b/src/arch/zx48k/library-asm/atan.asm index 049436b6a..83eb2c3b3 100644 --- a/src/arch/zx48k/library-asm/atan.asm +++ b/src/arch/zx48k/library-asm/atan.asm @@ -1,11 +1,15 @@ #include once + push namespace core + ATAN: ; Computes ATAN using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 24h ; ATAN + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 24h ; ATAN - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/attr.asm b/src/arch/zx48k/library-asm/attr.asm index 38349f797..b083d1f11 100644 --- a/src/arch/zx48k/library-asm/attr.asm +++ b/src/arch/zx48k/library-asm/attr.asm @@ -7,6 +7,8 @@ #include once #include once + push namespace core + __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -19,13 +21,13 @@ __ATTR_ADDR: add hl, hl ; HL = A * 8 ; 15 T-States add hl, hl ; HL = A * 16 ; 15 T-States add hl, hl ; HL = A * 32 ; 15 T-States - + ld d, 18h ; DE = 6144 + E. Note: 6144 is the screen size (before attr zone) add hl, de ld de, (SCREEN_ADDR) ; Adds the screen address add hl, de - + ; Return current screen address in HL ret @@ -41,7 +43,7 @@ SET_ATTR: __SET_ATTR: ; Internal __FASTCALL__ Entry used by printing routines - PROC + PROC call __ATTR_ADDR @@ -57,9 +59,9 @@ __SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address and e ; Mask current attributes or c ; Mix them ld (hl), a ; Store result in screen - + ret - + ENDP @@ -77,3 +79,5 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + + pop namespace diff --git a/src/arch/zx48k/library-asm/band16.asm b/src/arch/zx48k/library-asm/band16.asm index e1650f7c9..a6d1bc36c 100644 --- a/src/arch/zx48k/library-asm/band16.asm +++ b/src/arch/zx48k/library-asm/band16.asm @@ -1,19 +1,23 @@ ; vim:ts=4:et: ; FASTCALL bitwise and16 version. -; result in hl +; result in hl ; __FASTCALL__ version (operands: A, H) ; Performs 16bit or 16bit and returns the boolean ; Input: HL, DE ; Output: HL <- HL AND DE + push namespace core + __BAND16: - ld a, h - and d + ld a, h + and d ld h, a ld a, l and e ld l, a - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/band32.asm b/src/arch/zx48k/library-asm/band32.asm index 4c41a0c73..c9b855ca1 100644 --- a/src/arch/zx48k/library-asm/band32.asm +++ b/src/arch/zx48k/library-asm/band32.asm @@ -3,6 +3,8 @@ ; result in DE,HL ; First operand in DE,HL 2nd operand into the stack + push namespace core + __BAND32: ld b, h ld c, l ; BC <- HL @@ -10,7 +12,7 @@ __BAND32: pop hl ; Return address ex (sp), hl ; HL <- Lower part of 2nd Operand - ld a, b + ld a, b and h ld b, a @@ -18,7 +20,7 @@ __BAND32: and l ld c, a ; BC <- BC & HL - pop hl ; Return dddress + pop hl ; Return dddress ex (sp), hl ; HL <- High part of 2nd Operand ld a, d @@ -34,3 +36,5 @@ __BAND32: ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/beep.asm b/src/arch/zx48k/library-asm/beep.asm index bab803769..c52823e71 100644 --- a/src/arch/zx48k/library-asm/beep.asm +++ b/src/arch/zx48k/library-asm/beep.asm @@ -1,25 +1,29 @@ #include once + push namespace core + BEEP: ; The beep command, as in BASIC - ; Duration in C,ED,LH (float) - ; Pitch in top of the stack - - CALL __FPSTACK_PUSH - - pop hl ; RET address - pop af - pop de - pop bc ; Recovers PITCH from the stack - push hl ; CALLEE, now ret addr in top of the stack - - CALL __FPSTACK_PUSH ; Pitch onto the FP stack - - push ix ; BEEP routine modifies IX. We have to preserve it - call 03F8h - pop ix - ret - - + ; Duration in C,ED,LH (float) + ; Pitch in top of the stack + + CALL __FPSTACK_PUSH + + pop hl ; RET address + pop af + pop de + pop bc ; Recovers PITCH from the stack + push hl ; CALLEE, now ret addr in top of the stack + + CALL __FPSTACK_PUSH ; Pitch onto the FP stack + + push ix ; BEEP routine modifies IX. We have to preserve it + call 03F8h + pop ix + ret + + pop namespace + + diff --git a/src/arch/zx48k/library-asm/beeper.asm b/src/arch/zx48k/library-asm/beeper.asm index 4f1cbfd3b..958526c36 100644 --- a/src/arch/zx48k/library-asm/beeper.asm +++ b/src/arch/zx48k/library-asm/beeper.asm @@ -1,11 +1,13 @@ ; vim:ts=4:et:sw=4: ; This is a fast beep routine, but needs parameters -; codified in a different way. +; codified in a different way. ; See http://www.wearmouth.demon.co.uk/zx82.htm#L03F8 ; Needs pitch on top of the stack ; HL = duration + push namespace core + __BEEPER: ex de, hl pop hl @@ -15,4 +17,6 @@ __BEEPER: pop ix ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/bnot16.asm b/src/arch/zx48k/library-asm/bnot16.asm index 9d9a08f16..1718aee94 100644 --- a/src/arch/zx48k/library-asm/bnot16.asm +++ b/src/arch/zx48k/library-asm/bnot16.asm @@ -4,10 +4,12 @@ ; __FASTCALL__ version (operands: A, H) ; Performs 16bit NEGATION ; Input: HL -; Output: HL <- NOT HL +; Output: HL <- NOT HL + + push namespace core __BNOT16: - ld a, h + ld a, h cpl ld h, a @@ -15,5 +17,7 @@ __BNOT16: cpl ld l, a - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/bnot32.asm b/src/arch/zx48k/library-asm/bnot32.asm index 2d56888e1..97f6db5fd 100644 --- a/src/arch/zx48k/library-asm/bnot32.asm +++ b/src/arch/zx48k/library-asm/bnot32.asm @@ -4,24 +4,28 @@ ; __FASTCALL__ version (operands: A, H) ; Performs 32bit NEGATION (cpl) ; Input: DE,HL -; Output: DE,HL <- NOT DE,HL +; Output: DE,HL <- NOT DE,HL + + push namespace core __BNOT32: - ld a, l - cpl - ld l, a - - ld a, h - cpl - ld h, a - - ld a, e - cpl - ld e, a - - ld a, d - cpl - ld d, a - - ret + ld a, l + cpl + ld l, a + + ld a, h + cpl + ld h, a + + ld a, e + cpl + ld e, a + + ld a, d + cpl + ld d, a + + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/bold.asm b/src/arch/zx48k/library-asm/bold.asm index a834f42d9..4bd46a82e 100644 --- a/src/arch/zx48k/library-asm/bold.asm +++ b/src/arch/zx48k/library-asm/bold.asm @@ -2,29 +2,33 @@ ; Parameter: BOLD flag in bit 0 of A register #include once + push namespace core + BOLD: - PROC + PROC - and 1 - rlca + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/bor16.asm b/src/arch/zx48k/library-asm/bor16.asm index 35fc2845b..5dfa8a3f9 100644 --- a/src/arch/zx48k/library-asm/bor16.asm +++ b/src/arch/zx48k/library-asm/bor16.asm @@ -6,14 +6,18 @@ ; Input: HL, DE ; Output: HL <- HL OR DE + push namespace core + __BOR16: - ld a, h - or d + ld a, h + or d ld h, a ld a, l or e ld l, a - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/bor32.asm b/src/arch/zx48k/library-asm/bor32.asm index 0c2695636..b768ed358 100644 --- a/src/arch/zx48k/library-asm/bor32.asm +++ b/src/arch/zx48k/library-asm/bor32.asm @@ -3,6 +3,8 @@ ; result DE,HL ; First operand in DE,HL 2nd operand into the stack + push namespace core + __BOR32: ld b, h ld c, l ; BC <- HL @@ -10,7 +12,7 @@ __BOR32: pop hl ; Return address ex (sp), hl ; HL <- Lower part of 2nd Operand - ld a, b + ld a, b or h ld b, a @@ -18,7 +20,7 @@ __BOR32: or l ld c, a ; BC <- BC & HL - pop hl ; Return dddress + pop hl ; Return dddress ex (sp), hl ; HL <- High part of 2nd Operand ld a, d @@ -34,3 +36,5 @@ __BOR32: ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/border.asm b/src/arch/zx48k/library-asm/border.asm index d6d3be855..19c923194 100644 --- a/src/arch/zx48k/library-asm/border.asm +++ b/src/arch/zx48k/library-asm/border.asm @@ -1,7 +1,11 @@ ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core + BORDER EQU 229Bh -; Nothing to do! (Directly from the ZX Spectrum ROM) + pop namespace + +; Nothing to do! (Directly from the ZX Spectrum ROM) diff --git a/src/arch/zx48k/library-asm/bound.asm b/src/arch/zx48k/library-asm/bound.asm index 7e16683f2..7eb344b7e 100644 --- a/src/arch/zx48k/library-asm/bound.asm +++ b/src/arch/zx48k/library-asm/bound.asm @@ -1,6 +1,6 @@ ; --------------------------------------------------------- ; Copyleft (k)2011 by Jose Rodriguez (a.k.a. Boriel) -; http://www.boriel.com +; http://www.boriel.com ; ; ZX BASIC Compiler http://www.zxbasic.net ; This code is released under the BSD License @@ -11,6 +11,8 @@ ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core + PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -81,3 +83,5 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/break.asm b/src/arch/zx48k/library-asm/break.asm index ae8570858..9579232d5 100644 --- a/src/arch/zx48k/library-asm/break.asm +++ b/src/arch/zx48k/library-asm/break.asm @@ -6,6 +6,8 @@ ; L BREAK Into Program Error ; HL contains the line number we want to appear in the error msg. + push namespace core + CHECK_BREAK: PROC LOCAL PPC, TS_BRK, NO_BREAK @@ -29,3 +31,5 @@ TS_BRK EQU 8020 ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/bright.asm b/src/arch/zx48k/library-asm/bright.asm index 764935dbe..c4a7b58ed 100644 --- a/src/arch/zx48k/library-asm/bright.asm +++ b/src/arch/zx48k/library-asm/bright.asm @@ -3,40 +3,44 @@ #include once + push namespace core + BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/bxor16.asm b/src/arch/zx48k/library-asm/bxor16.asm index a0cdc55d7..7775c4033 100644 --- a/src/arch/zx48k/library-asm/bxor16.asm +++ b/src/arch/zx48k/library-asm/bxor16.asm @@ -6,14 +6,18 @@ ; Input: HL, DE ; Output: HL <- HL XOR DE + push namespace core + __BXOR16: - ld a, h - xor d + ld a, h + xor d ld h, a ld a, l xor e ld l, a - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/bxor32.asm b/src/arch/zx48k/library-asm/bxor32.asm index 089e60a7d..942f0f894 100644 --- a/src/arch/zx48k/library-asm/bxor32.asm +++ b/src/arch/zx48k/library-asm/bxor32.asm @@ -3,6 +3,8 @@ ; result DE,HL ; First operand in DE,HL 2nd operand into the stack + push namespace core + __BXOR32: ld b, h ld c, l ; BC <- HL @@ -10,7 +12,7 @@ __BXOR32: pop hl ; Return address ex (sp), hl ; HL <- Lower part of 2nd Operand - ld a, b + ld a, b xor h ld b, a @@ -18,7 +20,7 @@ __BXOR32: xor l ld c, a ; BC <- BC & HL - pop hl ; Return dddress + pop hl ; Return dddress ex (sp), hl ; HL <- High part of 2nd Operand ld a, d @@ -34,3 +36,5 @@ __BXOR32: ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/calloc.asm b/src/arch/zx48k/library-asm/calloc.asm index 6dca645aa..e069eecd2 100644 --- a/src/arch/zx48k/library-asm/calloc.asm +++ b/src/arch/zx48k/library-asm/calloc.asm @@ -24,22 +24,26 @@ ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core + __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/chr.asm b/src/arch/zx48k/library-asm/chr.asm index 1e3480c0f..b6709d146 100644 --- a/src/arch/zx48k/library-asm/chr.asm +++ b/src/arch/zx48k/library-asm/chr.asm @@ -3,73 +3,77 @@ #include once + push namespace core + CHR: ; Returns HL = Pointer to STRING (NULL if no memory) - ; Requires alloc.asm for dynamic memory heap. - ; Parameters: HL = Number of bytes to insert (already push onto the stack) - ; STACK => parameters (16 bit, only the High byte is considered) - ; Used registers A, A', BC, DE, HL, H'L' + ; Requires alloc.asm for dynamic memory heap. + ; Parameters: HL = Number of bytes to insert (already push onto the stack) + ; STACK => parameters (16 bit, only the High byte is considered) + ; Used registers A, A', BC, DE, HL, H'L' - PROC + PROC - LOCAL __POPOUT - LOCAL TMP + LOCAL __POPOUT + LOCAL TMP TMP EQU 23629 ; (DEST System variable) - ld a, h - or l - ret z ; If Number of parameters is ZERO, return NULL STRING + ld a, h + or l + ret z ; If Number of parameters is ZERO, return NULL STRING - ld b, h - ld c, l + ld b, h + ld c, l - pop hl ; Return address - ld (TMP), hl + pop hl ; Return address + ld (TMP), hl - push bc - inc bc - inc bc ; BC = BC + 2 => (2 bytes for the length number) - call __MEM_ALLOC - pop bc + push bc + inc bc + inc bc ; BC = BC + 2 => (2 bytes for the length number) + call __MEM_ALLOC + pop bc - ld d, h - ld e, l ; Saves HL in DE + ld d, h + ld e, l ; Saves HL in DE - ld a, h - or l - jr z, __POPOUT ; No Memory, return + ld a, h + or l + jr z, __POPOUT ; No Memory, return - ld (hl), c - inc hl - ld (hl), b - inc hl + ld (hl), c + inc hl + ld (hl), b + inc hl __POPOUT: ; Removes out of the stack every byte and return - ; If Zero Flag is set, don't store bytes in memory - ex af, af' ; Save Zero Flag + ; If Zero Flag is set, don't store bytes in memory + ex af, af' ; Save Zero Flag - ld a, b - or c - jr z, __CHR_END + ld a, b + or c + jr z, __CHR_END - dec bc - pop af ; Next byte + dec bc + pop af ; Next byte - ex af, af' ; Recovers Zero flag - jr z, __POPOUT + ex af, af' ; Recovers Zero flag + jr z, __POPOUT - ex af, af' ; Saves Zero flag - ld (hl), a - inc hl - ex af, af' ; Recovers Zero Flag + ex af, af' ; Saves Zero flag + ld (hl), a + inc hl + ex af, af' ; Recovers Zero Flag - jp __POPOUT + jp __POPOUT __CHR_END: - ld hl, (TMP) - push hl ; Restores return addr - ex de, hl ; Recovers original HL ptr - ret + ld hl, (TMP) + push hl ; Restores return addr + ex de, hl ; Recovers original HL ptr + ret + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/circle.asm b/src/arch/zx48k/library-asm/circle.asm index c388c44ac..a5f3515b2 100644 --- a/src/arch/zx48k/library-asm/circle.asm +++ b/src/arch/zx48k/library-asm/circle.asm @@ -8,210 +8,214 @@ ; Draws a circle at X, Y of radius R ; X, Y on the Stack, R in accumulator (Byte) - PROC - LOCAL __CIRCLE_ERROR - LOCAL __CIRCLE_LOOP - LOCAL __CIRCLE_NEXT + push namespace core + + PROC + LOCAL __CIRCLE_ERROR + LOCAL __CIRCLE_LOOP + LOCAL __CIRCLE_NEXT __CIRCLE_ERROR: - jp __OUT_OF_SCREEN_ERR + jp __OUT_OF_SCREEN_ERR CIRCLE: - ;; Entry point - pop hl ; Return Address - pop de ; D = Y - ex (sp), hl ; __CALLEE__ convention - ld e, h ; E = X - ld h, a ; H = R + ;; Entry point + pop hl ; Return Address + pop de ; D = Y + ex (sp), hl ; __CALLEE__ convention + ld e, h ; E = X + ld h, a ; H = R #ifdef SCREEN_Y_OFFSET - ld a, SCREEN_Y_OFFSET - add a, d - ld d, a + ld a, SCREEN_Y_OFFSET + add a, d + ld d, a #endif #ifdef SCREEN_X_OFFSET - ld a, SCREEN_X_OFFSET - add a, e - ld e, a + ld a, SCREEN_X_OFFSET + add a, e + ld e, a #endif - ld a, h - add a, d - sub 192 - jr nc, __CIRCLE_ERROR + ld a, h + add a, d + sub 192 + jr nc, __CIRCLE_ERROR - ld a, d - sub h - jr c, __CIRCLE_ERROR + ld a, d + sub h + jr c, __CIRCLE_ERROR - ld a, e - sub h - jr c, __CIRCLE_ERROR + ld a, e + sub h + jr c, __CIRCLE_ERROR - ld a, h - add a, e - jr c, __CIRCLE_ERROR + ld a, h + add a, e + jr c, __CIRCLE_ERROR ; __FASTCALL__ Entry: D, E = Y, X point of the center ; A = Radious __CIRCLE: - push de - ld a, h - exx - pop de ; D'E' = x0, y0 - ld h, a ; H' = r - - ld c, e - ld a, h - add a, d - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 + r) - - ld b, d - ld a, h - add a, e - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 + r, y0) - - ld c, e - ld a, d - sub h - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 - r) - - ld b, d - ld a, e - sub h - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 - r, y0) - - exx - ld b, 0 ; B = x = 0 - ld c, h ; C = y = Radius - ld hl, 1 - or a - sbc hl, bc ; HL = f = 1 - radius - - ex de, hl - ld hl, 0 - or a - sbc hl, bc ; HL = -radius - add hl, hl ; HL = -2 * radius - ex de, hl ; DE = -2 * radius = ddF_y, HL = f - - xor a ; A = ddF_x = 0 - ex af, af' ; Saves it + push de + ld a, h + exx + pop de ; D'E' = x0, y0 + ld h, a ; H' = r + + ld c, e + ld a, h + add a, d + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 + r) + + ld b, d + ld a, h + add a, e + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 + r, y0) + + ld c, e + ld a, d + sub h + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 - r) + + ld b, d + ld a, e + sub h + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 - r, y0) + + exx + ld b, 0 ; B = x = 0 + ld c, h ; C = y = Radius + ld hl, 1 + or a + sbc hl, bc ; HL = f = 1 - radius + + ex de, hl + ld hl, 0 + or a + sbc hl, bc ; HL = -radius + add hl, hl ; HL = -2 * radius + ex de, hl ; DE = -2 * radius = ddF_y, HL = f + + xor a ; A = ddF_x = 0 + ex af, af' ; Saves it __CIRCLE_LOOP: - ld a, b - cp c - ret nc ; Returns when x >= y + ld a, b + cp c + ret nc ; Returns when x >= y - bit 7, h ; HL >= 0? : if (f >= 0)... - jp nz, __CIRCLE_NEXT + bit 7, h ; HL >= 0? : if (f >= 0)... + jp nz, __CIRCLE_NEXT - dec c ; y-- - inc de - inc de ; ddF_y += 2 + dec c ; y-- + inc de + inc de ; ddF_y += 2 - add hl, de ; f += ddF_y + add hl, de ; f += ddF_y __CIRCLE_NEXT: - inc b ; x++ - ex af, af' - add a, 2 ; 1 Cycle faster than inc a, inc a - - inc hl ; f++ - push af - add a, l - ld l, a - ld a, h - adc a, 0 ; f = f + ddF_x - ld h, a - pop af - ex af, af' - - push bc - exx - pop hl ; H'L' = Y, X - - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) - - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) - - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) - - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) - - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) - - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - sub h - ld c, a ; C = x0 - y - call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) - - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) - - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - sub h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) - - exx - jp __CIRCLE_LOOP + inc b ; x++ + ex af, af' + add a, 2 ; 1 Cycle faster than inc a, inc a + + inc hl ; f++ + push af + add a, l + ld l, a + ld a, h + adc a, 0 ; f = f + ddF_x + ld h, a + pop af + ex af, af' + + push bc + exx + pop hl ; H'L' = Y, X + + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) + + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) + + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) + + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) + + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) + + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + sub h + ld c, a ; C = x0 - y + call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) + + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) + + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + sub h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) + + exx + jp __CIRCLE_LOOP __CIRCLE_PLOT: - ; Plots a point of the circle, preserving HL and DE - push hl - push de - call __PLOT - pop de - pop hl - ret - - ENDP + ; Plots a point of the circle, preserving HL and DE + push hl + push de + call __PLOT + pop de + pop hl + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/cls.asm b/src/arch/zx48k/library-asm/cls.asm index 8d689189e..437d47988 100644 --- a/src/arch/zx48k/library-asm/cls.asm +++ b/src/arch/zx48k/library-asm/cls.asm @@ -7,34 +7,36 @@ #include once + push namespace core + CLS: - PROC + PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - - ; Now clear attributes - - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + + ; Now clear attributes + + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) @@ -42,6 +44,8 @@ ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/const.asm b/src/arch/zx48k/library-asm/const.asm index 03e5e52ac..95a99b513 100644 --- a/src/arch/zx48k/library-asm/const.asm +++ b/src/arch/zx48k/library-asm/const.asm @@ -1,5 +1,7 @@ ; Global constants + push namespace core + P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -8,3 +10,5 @@ CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace + diff --git a/src/arch/zx48k/library-asm/copy_attr.asm b/src/arch/zx48k/library-asm/copy_attr.asm index 955d1db0d..3602f064d 100644 --- a/src/arch/zx48k/library-asm/copy_attr.asm +++ b/src/arch/zx48k/library-asm/copy_attr.asm @@ -4,73 +4,77 @@ #include once + push namespace core + COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl + ld hl, (ATTR_P) + ld (ATTR_T), hl + + ld hl, FLAGS2 + call __REFRESH_TMP - ld hl, FLAGS2 - call __REFRESH_TMP - - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) #ifdef ___PRINT_IS_USED___ - LOCAL TABLE - LOCAL CONT2 + LOCAL TABLE + LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 + ld c, a + ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE #else - ret + ret #endif __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/cos.asm b/src/arch/zx48k/library-asm/cos.asm index 69528453e..36739c87f 100644 --- a/src/arch/zx48k/library-asm/cos.asm +++ b/src/arch/zx48k/library-asm/cos.asm @@ -1,11 +1,15 @@ #include once + push namespace core + COS: ; Computes COS using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 20h ; COS + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 20h ; COS - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/div16.asm b/src/arch/zx48k/library-asm/div16.asm index 02ee5b816..437b89a5f 100644 --- a/src/arch/zx48k/library-asm/div16.asm +++ b/src/arch/zx48k/library-asm/div16.asm @@ -1,13 +1,15 @@ -; 16 bit division and modulo functions +; 16 bit division and modulo functions ; for both signed and unsigned values #include once + push namespace core + __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention @@ -38,7 +40,7 @@ __DIV16NOADD: __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl @@ -46,48 +48,48 @@ __MODU16: ; 16 bit modulus call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A + bit 7, d ; DE is negative? + jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' + call __DIVU16_FAST + ex af, af' - or a - ret p ; return if positive + or a + ret p ; return if positive jp __NEGHL - + __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl @@ -95,7 +97,9 @@ __MODI16: ; 16 bit modulus call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/div32.asm b/src/arch/zx48k/library-asm/div32.asm index 5008f8531..e3b9f5646 100644 --- a/src/arch/zx48k/library-asm/div32.asm +++ b/src/arch/zx48k/library-asm/div32.asm @@ -1,141 +1,145 @@ #include once - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core + __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - - adc hl, hl - exx - adc hl, hl - exx - - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + + adc hl, hl + exx + adc hl, hl + exx + + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl + exx + push de + push hl - exx - pop hl - pop de + exx + pop hl + pop de - ret + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - - jp __NEG32 ; Negates DEHL and returns from there - - + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + + jp __NEG32 ; Negates DEHL and returns from there + + __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + + call __DIVI32START + jp __MODU32START - call __DIVI32START - jp __MODU32START + pop namespace diff --git a/src/arch/zx48k/library-asm/div8.asm b/src/arch/zx48k/library-asm/div8.asm index fd185edd8..0c66b3f5f 100644 --- a/src/arch/zx48k/library-asm/div8.asm +++ b/src/arch/zx48k/library-asm/div8.asm @@ -1,87 +1,91 @@ - ; -------------------------------- -__DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; -------------------------------- + push namespace core + +__DIVU8: ; 8 bit unsigned integer division + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L + ld l, h + ld h, a ; At this point do H / L + + ld b, 8 + xor a ; A = 0, Carry Flag = 0 - ld b, 8 - xor a ; A = 0, Carry Flag = 0 - __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h + +__DIV8NOSUB: + djnz __DIV8LOOP -__DIV8NOSUB: - djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; - ld l, a ; save remainder - ld a, h ; - - ret ; a = Quotient, + ret ; a = Quotient, - ; -------------------------------- + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h + ld e, a ; store operands for later + ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' + ex af, af' - call __DIVU8_FAST + call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative + ld a, c + xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive + ld a, h ; Quotient + ret p ; return if positive + + neg + ret - neg - ret - __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder + call __DIVU8_FAST + ld a, l ; Remainder - ret ; a = Modulus + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder + call __DIVI8_FAST + ld a, l ; remainder + + ret ; a = Modulus - ret ; a = Modulus + pop namespace diff --git a/src/arch/zx48k/library-asm/divf.asm b/src/arch/zx48k/library-asm/divf.asm index 1f31e6b76..fa5500a5c 100644 --- a/src/arch/zx48k/library-asm/divf.asm +++ b/src/arch/zx48k/library-asm/divf.asm @@ -11,50 +11,54 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __DIVF: ; Division - PROC - LOCAL __DIVBYZERO - LOCAL TMP, ERR_SP + PROC + LOCAL __DIVBYZERO + LOCAL TMP, ERR_SP TMP EQU 23629 ;(DEST) ERR_SP EQU 23613 - call __FPSTACK_PUSH2 + call __FPSTACK_PUSH2 + + ld hl, (ERR_SP) + ld (TMP), hl + ld hl, __DIVBYZERO + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl - ld hl, (ERR_SP) - ld (TMP), hl - ld hl, __DIVBYZERO - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - - ; ------------- ROM DIV - rst 28h - defb 01h ; EXCHANGE - defb 05h ; DIV - defb 38h; ; END CALC + ; ------------- ROM DIV + rst 28h + defb 01h ; EXCHANGE + defb 05h ; DIV + defb 38h; ; END CALC - pop hl - ld hl, (TMP) - ld (ERR_SP), hl + pop hl + ld hl, (TMP) + ld (ERR_SP), hl - jp __FPSTACK_POP + jp __FPSTACK_POP __DIVBYZERO: - ld hl, (TMP) - ld (ERR_SP), hl + ld hl, (TMP) + ld (ERR_SP), hl + + ld a, ERROR_NumberTooBig + ld (ERR_NR), a - ld a, ERROR_NumberTooBig - ld (ERR_NR), a + ; Returns 0 on DIV BY ZERO error + xor a + ld b, a + ld c, a + ld d, a + ld e, a + ret - ; Returns 0 on DIV BY ZERO error - xor a - ld b, a - ld c, a - ld d, a - ld e, a - ret + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/divf16.asm b/src/arch/zx48k/library-asm/divf16.asm index 790946a11..96cc03530 100644 --- a/src/arch/zx48k/library-asm/divf16.asm +++ b/src/arch/zx48k/library-asm/divf16.asm @@ -1,83 +1,87 @@ -#include once - - -__DIVF16: ; 16.16 Fixed point Division (signed) - - ; DE.HL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - ex de, hl ; D'E'.H'L' Dividend - -__DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - - exx ; Now works with D'E'.H'L' - ex af, af' - xor d - ex af, af' ; Stores sign of the result for later - - bit 7, d ; Negative? - call nz, __NEG32 - exx ; Now we have DE.HL => Dividend - - ld b, 16 - -__SHIFTALOOP: ; Tries to shift Dividend to the left - bit 7, d - jp nz, __SHIFTB - add hl, hl - ex de, hl - adc hl, hl - ex de, hl - djnz __SHIFTALOOP - jp __DOF16_DIVRDY - -__SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right - ld a, b - exx - ld b, a - ; Divisor is in DEHL -__SHIFTBLOOP: - bit 1, l - jp nz, __DOF16_DIVIDE - sra d - rr e - rr h - rr l - djnz __SHIFTBLOOP - -__DOF16_DIVIDE: - ld a, b - exx - ld b, a - -__DOF16_DIVRDY: - exx - ex de, hl - push bc - call __DIVU32START - pop bc - - xor a - or b - jp z, __ENDF16DIV - -__SHIFTCLOOP: - add hl, hl ; Shift DECIMAL PART << 1 - ex de, hl - adc hl, hl ; Shift INTEGER PART << 1 Plus Carry - ex de, hl - djnz __SHIFTCLOOP - -__ENDF16DIV: ; Put the sign on the result - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there - +#include once + + + push namespace core + +__DIVF16: ; 16.16 Fixed point Division (signed) + + ; DE.HL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ex de, hl ; D'E'.H'L' Dividend + +__DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + + exx ; Now works with D'E'.H'L' + ex af, af' + xor d + ex af, af' ; Stores sign of the result for later + + bit 7, d ; Negative? + call nz, __NEG32 + exx ; Now we have DE.HL => Dividend + + ld b, 16 + +__SHIFTALOOP: ; Tries to shift Dividend to the left + bit 7, d + jp nz, __SHIFTB + add hl, hl + ex de, hl + adc hl, hl + ex de, hl + djnz __SHIFTALOOP + jp __DOF16_DIVRDY + +__SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right + ld a, b + exx + ld b, a + ; Divisor is in DEHL +__SHIFTBLOOP: + bit 1, l + jp nz, __DOF16_DIVIDE + sra d + rr e + rr h + rr l + djnz __SHIFTBLOOP + +__DOF16_DIVIDE: + ld a, b + exx + ld b, a + +__DOF16_DIVRDY: + exx + ex de, hl + push bc + call __DIVU32START + pop bc + + xor a + or b + jp z, __ENDF16DIV + +__SHIFTCLOOP: + add hl, hl ; Shift DECIMAL PART << 1 + ex de, hl + adc hl, hl ; Shift INTEGER PART << 1 Plus Carry + ex de, hl + djnz __SHIFTCLOOP + +__ENDF16DIV: ; Put the sign on the result + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there + + pop namespace + diff --git a/src/arch/zx48k/library-asm/draw.asm b/src/arch/zx48k/library-asm/draw.asm index 46ffe82c6..2037d18a0 100644 --- a/src/arch/zx48k/library-asm/draw.asm +++ b/src/arch/zx48k/library-asm/draw.asm @@ -17,7 +17,9 @@ #include once ;; DRAW PROCEDURE - PROC + push namespace core + + PROC LOCAL __DRAW1 LOCAL __DRAW2 @@ -55,7 +57,7 @@ DRAW: ld a, b add a, e - ld e, a + ld e, a ld a, d adc a, 0 ; DE = DE + B ld d, a @@ -112,14 +114,14 @@ __PIXEL_MASK: ld b, d ; Restores B' from D' pop de ; D'E' = y2, x2 exx ; At this point: D'E' = y2,x2 coords - ; B'C' = y1, y1 coords + ; B'C' = y1, y1 coords ex af, af' ; Saves A reg for later - ; A' = Pixel mask - ; H'L' = Screen Address of pixel + ; A' = Pixel mask + ; H'L' = Screen Address of pixel ld bc, (COORDS) ; B,C = y1, x1 - ld a, e + ld a, e sub c ; dx = X2 - X1 ld c, a ; Saves dx in c @@ -192,10 +194,10 @@ __DRAW3: ; While c != e => while y != y2 add hl, de ; error -= dX bit 7, h ; exx ; recover coordinates - jr z, __DRAW4 ; if error < 0 + jr z, __DRAW4 ; if error < 0 exx - add hl, bc ; error += dY + add hl, bc ; error += dY exx ld a, e @@ -203,7 +205,7 @@ DX1: ; x += xi inc c call __INCX ; This address will be dynamically updated ld e, a - + __DRAW4: DY1: ; y += yi @@ -217,13 +219,13 @@ __DRAW4_LOOP: cp d jp nz, __DRAW3 ld (COORDS), bc - ret + ret __DRAW_DX_GT_DY: ; DX > DY ; -------------------------- ; HL = error = dX / 2 ld h, 0 - ld l, c + ld l, c srl l ; HL = error = DX / 2 ; DE = -dY @@ -248,15 +250,15 @@ __DRAW5: ; While loop add hl, de ; error -= dY bit 7, h ; if (error < 0) exx ; Restore coords - jr z, __DRAW6 ; + jr z, __DRAW6 ; exx add hl, bc ; error += dX - exx + exx DY2: ; y += yi inc b call __INCY ; This address will be dynamically updated - + __DRAW6: ld a, e DX2: ; x += xi @@ -271,7 +273,7 @@ __DRAW6_LOOP: jp nz, __DRAW5 ld (COORDS), bc ret - + COORDS EQU 5C7Dh __DRAW_END: @@ -303,7 +305,7 @@ __PLOTINVERSE: nop ; Replace with CPL if INVERSE 1 __PLOTOVER: or (hl) ; Replace with XOR (hl) if OVER 1 AND INVERSE 0 - ; Replace with AND (hl) if INVERSE 1 + ; Replace with AND (hl) if INVERSE 1 ld (hl), a ex af, af' ; Recovers flag. If Carry set => update ATTR @@ -318,8 +320,8 @@ __PLOTOVER: pop de pop hl - LOCAL __FASTPLOTEND -__FASTPLOTEND: + LOCAL __FASTPLOTEND +__FASTPLOTEND: or a ; Resets carry flag ex af, af' ; Recovers A reg ld a, e @@ -327,3 +329,5 @@ __FASTPLOTEND: ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/draw3.asm b/src/arch/zx48k/library-asm/draw3.asm index 52c0ac737..511be8f15 100644 --- a/src/arch/zx48k/library-asm/draw3.asm +++ b/src/arch/zx48k/library-asm/draw3.asm @@ -1,5 +1,5 @@ ; ----------------------------------------------------------- -; vim: et:ts=4:sw=4:ruler: +; vim: et:ts=4:sw=4:ruler: ; ; DRAW an arc using ZX ROM algorithm. ; DRAW x, y, r => r = Arc in radians @@ -14,124 +14,126 @@ ; Ripped from the ZX Spectrum ROM + push namespace core + DRAW3: - PROC - LOCAL STACK_TO_BC - LOCAL STACK_TO_A - LOCAL COORDS - LOCAL L2477 - LOCAL L2420 - LOCAL L2439 - LOCAL L245F - LOCAL L23C1 - LOCAL L2D28 - LOCAL SUM_C, SUM_B + PROC + LOCAL STACK_TO_BC + LOCAL STACK_TO_A + LOCAL COORDS + LOCAL L2477 + LOCAL L2420 + LOCAL L2439 + LOCAL L245F + LOCAL L23C1 + LOCAL L2D28 + LOCAL SUM_C, SUM_B L2D28 EQU 02D28h COORDS EQU 5C7Dh STACK_TO_BC EQU 2307h STACK_TO_A EQU 2314h - exx - ex af, af' ;; Preserves ARC - pop hl - pop de - ex (sp), hl ;; CALLEE - push de - call __FPSTACK_I16 ;; X Offset - pop hl - call __FPSTACK_I16 ;; Y Offset - exx - ex af, af' - call __FPSTACK_PUSH ;; R Arc - -; Now enter the calculator and store the complete rotation angle in mem-5 - - RST 28H ;; FP-CALC x, y, A. - DEFB $C5 ;;st-mem-5 x, y, A. + exx + ex af, af' ;; Preserves ARC + pop hl + pop de + ex (sp), hl ;; CALLEE + push de + call __FPSTACK_I16 ;; X Offset + pop hl + call __FPSTACK_I16 ;; Y Offset + exx + ex af, af' + call __FPSTACK_PUSH ;; R Arc + +; Now enter the calculator and store the complete rotation angle in mem-5 + + RST 28H ;; FP-CALC x, y, A. + DEFB $C5 ;;st-mem-5 x, y, A. ; Test the angle for the special case of 360 degrees. - DEFB $A2 ;;stk-half x, y, A, 1/2. - DEFB $04 ;;multiply x, y, A/2. - DEFB $1F ;;sin x, y, sin(A/2). - DEFB $31 ;;duplicate x, y, sin(A/2),sin(A/2) - DEFB $30 ;;not x, y, sin(A/2), (0/1). - DEFB $30 ;;not x, y, sin(A/2), (1/0). - DEFB $00 ;;jump-true x, y, sin(A/2). + DEFB $A2 ;;stk-half x, y, A, 1/2. + DEFB $04 ;;multiply x, y, A/2. + DEFB $1F ;;sin x, y, sin(A/2). + DEFB $31 ;;duplicate x, y, sin(A/2),sin(A/2) + DEFB $30 ;;not x, y, sin(A/2), (0/1). + DEFB $30 ;;not x, y, sin(A/2), (1/0). + DEFB $00 ;;jump-true x, y, sin(A/2). - DEFB $06 ;;forward to L23A3, DR-SIN-NZ - ;;if sin(r/2) is not zero. + DEFB $06 ;;forward to L23A3, DR-SIN-NZ + ;;if sin(r/2) is not zero. ; The third parameter is 2*PI (or a multiple of 2*PI) so a 360 degrees turn -; would just be a straight line. Eliminating this case here prevents +; would just be a straight line. Eliminating this case here prevents ; division by zero at later stage. - DEFB $02 ;;delete x, y. - DEFB $38 ;;end-calc x, y. - JP L2477 + DEFB $02 ;;delete x, y. + DEFB $38 ;;end-calc x, y. + JP L2477 ; --- ; An arc can be drawn. ;; DR-SIN-NZ - DEFB $C0 ;;st-mem-0 x, y, sin(A/2). store mem-0 - DEFB $02 ;;delete x, y. + DEFB $C0 ;;st-mem-0 x, y, sin(A/2). store mem-0 + DEFB $02 ;;delete x, y. -; The next step calculates (roughly) the diameter of the circle of which the +; The next step calculates (roughly) the diameter of the circle of which the ; arc will form part. This value does not have to be too accurate as it is ; only used to evaluate the number of straight lines and then discarded. -; After all for a circle, the radius is used. Consequently, a circle of +; After all for a circle, the radius is used. Consequently, a circle of ; radius 50 will have 24 straight lines but an arc of radius 50 will have 20 ; straight lines - when drawn in any direction. -; So that simple arithmetic can be used, the length of the chord can be +; So that simple arithmetic can be used, the length of the chord can be ; calculated as X+Y rather than by Pythagoras Theorem and the sine of the ; nearest angle within reach is used. - DEFB $C1 ;;st-mem-1 x, y. store mem-1 - DEFB $02 ;;delete x. + DEFB $C1 ;;st-mem-1 x, y. store mem-1 + DEFB $02 ;;delete x. - DEFB $31 ;;duplicate x, x. - DEFB $2A ;;abs x, x (+ve). - DEFB $E1 ;;get-mem-1 x, X, y. - DEFB $01 ;;exchange x, y, X. - DEFB $E1 ;;get-mem-1 x, y, X, y. - DEFB $2A ;;abs x, y, X, Y (+ve). - DEFB $0F ;;addition x, y, X+Y. - DEFB $E0 ;;get-mem-0 x, y, X+Y, sin(A/2). - DEFB $05 ;;division x, y, X+Y/sin(A/2). - DEFB $2A ;;abs x, y, X+Y/sin(A/2) = D. + DEFB $31 ;;duplicate x, x. + DEFB $2A ;;abs x, x (+ve). + DEFB $E1 ;;get-mem-1 x, X, y. + DEFB $01 ;;exchange x, y, X. + DEFB $E1 ;;get-mem-1 x, y, X, y. + DEFB $2A ;;abs x, y, X, Y (+ve). + DEFB $0F ;;addition x, y, X+Y. + DEFB $E0 ;;get-mem-0 x, y, X+Y, sin(A/2). + DEFB $05 ;;division x, y, X+Y/sin(A/2). + DEFB $2A ;;abs x, y, X+Y/sin(A/2) = D. ; Bring back sin(A/2) from mem-0 which will shortly get trashed. ; Then bring D to the top of the stack again. - DEFB $E0 ;;get-mem-0 x, y, D, sin(A/2). - DEFB $01 ;;exchange x, y, sin(A/2), D. + DEFB $E0 ;;get-mem-0 x, y, D, sin(A/2). + DEFB $01 ;;exchange x, y, sin(A/2), D. ; Note. that since the value at the top of the stack has arisen as a result ; of division then it can no longer be in integer form and the next re-stack ; is unnecessary. Only the Sinclair ZX80 had integer division. - ;;DEFB $3D ;;re-stack (unnecessary) + ;;DEFB $3D ;;re-stack (unnecessary) - DEFB $38 ;;end-calc x, y, sin(A/2), D. + DEFB $38 ;;end-calc x, y, sin(A/2), D. ; The next test avoids drawing 4 straight lines when the start and end pixels ; are adjacent (or the same) but is probably best dispensed with. - LD A,(HL) ; fetch exponent byte of D. - CP $81 ; compare to 1 - JR NC,L23C1 ; forward, if > 1, to DR-PRMS + LD A,(HL) ; fetch exponent byte of D. + CP $81 ; compare to 1 + JR NC,L23C1 ; forward, if > 1, to DR-PRMS ; else delete the top two stack values and draw a simple straight line. - RST 28H ;; FP-CALC - DEFB $02 ;;delete - DEFB $02 ;;delete - DEFB $38 ;;end-calc x, y. + RST 28H ;; FP-CALC + DEFB $02 ;;delete + DEFB $02 ;;delete + DEFB $38 ;;end-calc x, y. - JP L2477 ; to LINE-DRAW + JP L2477 ; to LINE-DRAW ; --- @@ -143,250 +145,250 @@ STACK_TO_A EQU 2314h ;; DR-PRMS L23C1: CALL 247Dh ; routine CD-PRMS1 - ; mem-0 ; (A)/No. of lines (=a) (step angle) - ; mem-1 ; sin(a/2) - ; mem-2 ; - - ; mem-3 ; cos(a) const - ; mem-4 ; sin(a) const - ; mem-5 ; Angle of rotation (A) in - ; B ; Count of straight lines - max 252. + ; mem-0 ; (A)/No. of lines (=a) (step angle) + ; mem-1 ; sin(a/2) + ; mem-2 ; - + ; mem-3 ; cos(a) const + ; mem-4 ; sin(a) const + ; mem-5 ; Angle of rotation (A) in + ; B ; Count of straight lines - max 252. - PUSH BC ; Save the line count on the machine stack. + PUSH BC ; Save the line count on the machine stack. ; Remove the now redundant diameter value D. - RST 28H ;; FP-CALC x, y, sin(A/2), D. - DEFB $02 ;;delete x, y, sin(A/2). + RST 28H ;; FP-CALC x, y, sin(A/2), D. + DEFB $02 ;;delete x, y, sin(A/2). ; Dividing the sine of the step angle by the sine of the total angle gives ; the length of the initial chord on a unary circle. This factor f is used -; to scale the coordinates of the first line which still points in the +; to scale the coordinates of the first line which still points in the ; direction of the end point and may be larger. - DEFB $E1 ;;get-mem-1 x, y, sin(A/2), sin(a/2) - DEFB $01 ;;exchange x, y, sin(a/2), sin(A/2) - DEFB $05 ;;division x, y, sin(a/2)/sin(A/2) - DEFB $C1 ;;st-mem-1 x, y. f. - DEFB $02 ;;delete x, y. + DEFB $E1 ;;get-mem-1 x, y, sin(A/2), sin(a/2) + DEFB $01 ;;exchange x, y, sin(a/2), sin(A/2) + DEFB $05 ;;division x, y, sin(a/2)/sin(A/2) + DEFB $C1 ;;st-mem-1 x, y. f. + DEFB $02 ;;delete x, y. ; With the factor stored, scale the x coordinate first. - DEFB $01 ;;exchange y, x. - DEFB $31 ;;duplicate y, x, x. - DEFB $E1 ;;get-mem-1 y, x, x, f. - DEFB $04 ;;multiply y, x, x*f (=xx) - DEFB $C2 ;;st-mem-2 y, x, xx. - DEFB $02 ;;delete y. x. + DEFB $01 ;;exchange y, x. + DEFB $31 ;;duplicate y, x, x. + DEFB $E1 ;;get-mem-1 y, x, x, f. + DEFB $04 ;;multiply y, x, x*f (=xx) + DEFB $C2 ;;st-mem-2 y, x, xx. + DEFB $02 ;;delete y. x. ; Now scale the y coordinate. - DEFB $01 ;;exchange x, y. - DEFB $31 ;;duplicate x, y, y. - DEFB $E1 ;;get-mem-1 x, y, y, f - DEFB $04 ;;multiply x, y, y*f (=yy) + DEFB $01 ;;exchange x, y. + DEFB $31 ;;duplicate x, y, y. + DEFB $E1 ;;get-mem-1 x, y, y, f + DEFB $04 ;;multiply x, y, y*f (=yy) -; Note. 'sin' and 'cos' trash locations mem-0 to mem-2 so fetch mem-2 to the +; Note. 'sin' and 'cos' trash locations mem-0 to mem-2 so fetch mem-2 to the ; calculator stack for safe keeping. - DEFB $E2 ;;get-mem-2 x, y, yy, xx. + DEFB $E2 ;;get-mem-2 x, y, yy, xx. ; Once we get the coordinates of the first straight line then the 'ROTATION ; FORMULA' used in the arc loop will take care of all other points, but we ; now use a variation of that formula to rotate the first arc through (A-a)/2 -; radians. -; +; radians. +; ; xRotated = y * sin(angle) + x * cos(angle) ; yRotated = y * cos(angle) - x * sin(angle) ; - - DEFB $E5 ;;get-mem-5 x, y, yy, xx, A. - DEFB $E0 ;;get-mem-0 x, y, yy, xx, A, a. - DEFB $03 ;;subtract x, y, yy, xx, A-a. - DEFB $A2 ;;stk-half x, y, yy, xx, A-a, 1/2. - DEFB $04 ;;multiply x, y, yy, xx, (A-a)/2. (=angle) - DEFB $31 ;;duplicate x, y, yy, xx, angle, angle. - DEFB $1F ;;sin x, y, yy, xx, angle, sin(angle) - DEFB $C5 ;;st-mem-5 x, y, yy, xx, angle, sin(angle) - DEFB $02 ;;delete x, y, yy, xx, angle - - DEFB $20 ;;cos x, y, yy, xx, cos(angle). + + DEFB $E5 ;;get-mem-5 x, y, yy, xx, A. + DEFB $E0 ;;get-mem-0 x, y, yy, xx, A, a. + DEFB $03 ;;subtract x, y, yy, xx, A-a. + DEFB $A2 ;;stk-half x, y, yy, xx, A-a, 1/2. + DEFB $04 ;;multiply x, y, yy, xx, (A-a)/2. (=angle) + DEFB $31 ;;duplicate x, y, yy, xx, angle, angle. + DEFB $1F ;;sin x, y, yy, xx, angle, sin(angle) + DEFB $C5 ;;st-mem-5 x, y, yy, xx, angle, sin(angle) + DEFB $02 ;;delete x, y, yy, xx, angle + + DEFB $20 ;;cos x, y, yy, xx, cos(angle). ; Note. mem-0, mem-1 and mem-2 can be used again now... - DEFB $C0 ;;st-mem-0 x, y, yy, xx, cos(angle). - DEFB $02 ;;delete x, y, yy, xx. - - DEFB $C2 ;;st-mem-2 x, y, yy, xx. - DEFB $02 ;;delete x, y, yy. - - DEFB $C1 ;;st-mem-1 x, y, yy. - DEFB $E5 ;;get-mem-5 x, y, yy, sin(angle) - DEFB $04 ;;multiply x, y, yy*sin(angle). - DEFB $E0 ;;get-mem-0 x, y, yy*sin(angle), cos(angle) - DEFB $E2 ;;get-mem-2 x, y, yy*sin(angle), cos(angle), xx. - DEFB $04 ;;multiply x, y, yy*sin(angle), xx*cos(angle). - DEFB $0F ;;addition x, y, xRotated. - DEFB $E1 ;;get-mem-1 x, y, xRotated, yy. - DEFB $01 ;;exchange x, y, yy, xRotated. - DEFB $C1 ;;st-mem-1 x, y, yy, xRotated. - DEFB $02 ;;delete x, y, yy. - - DEFB $E0 ;;get-mem-0 x, y, yy, cos(angle). - DEFB $04 ;;multiply x, y, yy*cos(angle). - DEFB $E2 ;;get-mem-2 x, y, yy*cos(angle), xx. - DEFB $E5 ;;get-mem-5 x, y, yy*cos(angle), xx, sin(angle). - DEFB $04 ;;multiply x, y, yy*cos(angle), xx*sin(angle). - DEFB $03 ;;subtract x, y, yRotated. - DEFB $C2 ;;st-mem-2 x, y, yRotated. - -; Now the initial x and y coordinates are made positive and summed to see + DEFB $C0 ;;st-mem-0 x, y, yy, xx, cos(angle). + DEFB $02 ;;delete x, y, yy, xx. + + DEFB $C2 ;;st-mem-2 x, y, yy, xx. + DEFB $02 ;;delete x, y, yy. + + DEFB $C1 ;;st-mem-1 x, y, yy. + DEFB $E5 ;;get-mem-5 x, y, yy, sin(angle) + DEFB $04 ;;multiply x, y, yy*sin(angle). + DEFB $E0 ;;get-mem-0 x, y, yy*sin(angle), cos(angle) + DEFB $E2 ;;get-mem-2 x, y, yy*sin(angle), cos(angle), xx. + DEFB $04 ;;multiply x, y, yy*sin(angle), xx*cos(angle). + DEFB $0F ;;addition x, y, xRotated. + DEFB $E1 ;;get-mem-1 x, y, xRotated, yy. + DEFB $01 ;;exchange x, y, yy, xRotated. + DEFB $C1 ;;st-mem-1 x, y, yy, xRotated. + DEFB $02 ;;delete x, y, yy. + + DEFB $E0 ;;get-mem-0 x, y, yy, cos(angle). + DEFB $04 ;;multiply x, y, yy*cos(angle). + DEFB $E2 ;;get-mem-2 x, y, yy*cos(angle), xx. + DEFB $E5 ;;get-mem-5 x, y, yy*cos(angle), xx, sin(angle). + DEFB $04 ;;multiply x, y, yy*cos(angle), xx*sin(angle). + DEFB $03 ;;subtract x, y, yRotated. + DEFB $C2 ;;st-mem-2 x, y, yRotated. + +; Now the initial x and y coordinates are made positive and summed to see ; if they measure up to anything significant. - DEFB $2A ;;abs x, y, yRotated'. - DEFB $E1 ;;get-mem-1 x, y, yRotated', xRotated. - DEFB $2A ;;abs x, y, yRotated', xRotated'. - DEFB $0F ;;addition x, y, yRotated+xRotated. - DEFB $02 ;;delete x, y. + DEFB $2A ;;abs x, y, yRotated'. + DEFB $E1 ;;get-mem-1 x, y, yRotated', xRotated. + DEFB $2A ;;abs x, y, yRotated', xRotated'. + DEFB $0F ;;addition x, y, yRotated+xRotated. + DEFB $02 ;;delete x, y. - DEFB $38 ;;end-calc x, y. + DEFB $38 ;;end-calc x, y. ; Although the test value has been deleted it is still above the calculator ; stack in memory and conveniently DE which points to the first free byte ; addresses the exponent of the test value. - LD A,(DE) ; Fetch exponent of the length indicator. - CP $81 ; Compare to that for 1 + LD A,(DE) ; Fetch exponent of the length indicator. + CP $81 ; Compare to that for 1 - POP BC ; Balance the machine stack + POP BC ; Balance the machine stack - JP C,L2477 ; forward, if the coordinates of first line - ; don't add up to more than 1, to LINE-DRAW + JP C,L2477 ; forward, if the coordinates of first line + ; don't add up to more than 1, to LINE-DRAW ; Continue when the arc will have a discernable shape. - PUSH BC ; Restore line counter to the machine stack. + PUSH BC ; Restore line counter to the machine stack. -; The parameters of the DRAW command were relative and they are now converted -; to absolute coordinates by adding to the coordinates of the last point -; plotted. The first two values on the stack are the terminal tx and ty -; coordinates. The x-coordinate is converted first but first the last point -; plotted is saved as it will initialize the moving ax, value. +; The parameters of the DRAW command were relative and they are now converted +; to absolute coordinates by adding to the coordinates of the last point +; plotted. The first two values on the stack are the terminal tx and ty +; coordinates. The x-coordinate is converted first but first the last point +; plotted is saved as it will initialize the moving ax, value. - RST 28H ;; FP-CALC x, y. - DEFB $01 ;;exchange y, x. - DEFB $38 ;;end-calc y, x. + RST 28H ;; FP-CALC x, y. + DEFB $01 ;;exchange y, x. + DEFB $38 ;;end-calc y, x. - LD A,(COORDS) ;; Fetch System Variable COORDS-x - CALL L2D28 ;; routine STACK-A + LD A,(COORDS) ;; Fetch System Variable COORDS-x + CALL L2D28 ;; routine STACK-A - RST 28H ;; FP-CALC y, x, last-x. + RST 28H ;; FP-CALC y, x, last-x. ; Store the last point plotted to initialize the moving ax value. - DEFB $C0 ;;st-mem-0 y, x, last-x. - DEFB $0F ;;addition y, absolute x. - DEFB $01 ;;exchange tx, y. - DEFB $38 ;;end-calc tx, y. + DEFB $C0 ;;st-mem-0 y, x, last-x. + DEFB $0F ;;addition y, absolute x. + DEFB $01 ;;exchange tx, y. + DEFB $38 ;;end-calc tx, y. - LD A,(COORDS + 1) ; Fetch System Variable COORDS-y - CALL L2D28 ; routine STACK-A + LD A,(COORDS + 1) ; Fetch System Variable COORDS-y + CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC tx, y, last-y. + RST 28H ;; FP-CALC tx, y, last-y. ; Store the last point plotted to initialize the moving ay value. - DEFB $C5 ;;st-mem-5 tx, y, last-y. - DEFB $0F ;;addition tx, ty. + DEFB $C5 ;;st-mem-5 tx, y, last-y. + DEFB $0F ;;addition tx, ty. ; Fetch the moving ax and ay to the calculator stack. - DEFB $E0 ;;get-mem-0 tx, ty, ax. - DEFB $E5 ;;get-mem-5 tx, ty, ax, ay. - DEFB $38 ;;end-calc tx, ty, ax, ay. + DEFB $E0 ;;get-mem-0 tx, ty, ax. + DEFB $E5 ;;get-mem-5 tx, ty, ax, ay. + DEFB $38 ;;end-calc tx, ty, ax, ay. - POP BC ; Restore the straight line count. + POP BC ; Restore the straight line count. ; ----------------------------------- ; THE 'CIRCLE/DRAW CONVERGENCE POINT' ; ----------------------------------- -; The CIRCLE and ARC-DRAW commands converge here. +; The CIRCLE and ARC-DRAW commands converge here. ; -; Note. for both the CIRCLE and ARC commands the minimum initial line count -; is 4 (as set up by the CD_PARAMS routine) and so the zero flag will never +; Note. for both the CIRCLE and ARC commands the minimum initial line count +; is 4 (as set up by the CD_PARAMS routine) and so the zero flag will never ; be set and the loop is always entered. The first test is superfluous and ; the jump will always be made to ARC-START. ;; DRW-STEPS -L2420: DEC B ; decrement the arc count (4,8,12,16...). +L2420: DEC B ; decrement the arc count (4,8,12,16...). - ;JR Z,L245F ; forward, if zero (not possible), to ARC-END + ;JR Z,L245F ; forward, if zero (not possible), to ARC-END - JP L2439 ; forward to ARC-START + JP L2439 ; forward to ARC-START ; -------------- ; THE 'ARC LOOP' ; -------------- ; -; The arc drawing loop will draw up to 31 straight lines for a circle and up +; The arc drawing loop will draw up to 31 straight lines for a circle and up ; 251 straight lines for an arc between two points. In both cases the final -; closing straight line is drawn at ARC_END, but it otherwise loops back to +; closing straight line is drawn at ARC_END, but it otherwise loops back to ; here to calculate the next coordinate using the ROTATION FORMULA where (a) ; is the previously calculated, constant CENTRAL ANGLE of the arcs. ; ; Xrotated = x * cos(a) - y * sin(a) ; Yrotated = x * sin(a) + y * cos(a) ; -; The values cos(a) and sin(a) are pre-calculated and held in mem-3 and mem-4 +; The values cos(a) and sin(a) are pre-calculated and held in mem-3 and mem-4 ; for the duration of the routine. ; Memory location mem-1 holds the last relative x value (rx) and mem-2 holds ; the last relative y value (ry) used by DRAW. ; ; Note. that this is a very clever twist on what is after all a very clever, ; well-used formula. Normally the rotation formula is used with the x and y -; coordinates from the centre of the circle (or arc) and a supplied angle to -; produce two new x and y coordinates in an anticlockwise direction on the +; coordinates from the centre of the circle (or arc) and a supplied angle to +; produce two new x and y coordinates in an anticlockwise direction on the ; circumference of the circle. ; What is being used here, instead, is the relative X and Y parameters from -; the last point plotted that are required to get to the current point and -; the formula returns the next relative coordinates to use. +; the last point plotted that are required to get to the current point and +; the formula returns the next relative coordinates to use. ;; ARC-LOOP -L2425: RST 28H ;; FP-CALC - DEFB $E1 ;;get-mem-1 rx. - DEFB $31 ;;duplicate rx, rx. - DEFB $E3 ;;get-mem-3 cos(a) - DEFB $04 ;;multiply rx, rx*cos(a). - DEFB $E2 ;;get-mem-2 rx, rx*cos(a), ry. - DEFB $E4 ;;get-mem-4 rx, rx*cos(a), ry, sin(a). - DEFB $04 ;;multiply rx, rx*cos(a), ry*sin(a). - DEFB $03 ;;subtract rx, rx*cos(a) - ry*sin(a) - DEFB $C1 ;;st-mem-1 rx, new relative x rotated. - DEFB $02 ;;delete rx. - - DEFB $E4 ;;get-mem-4 rx, sin(a). - DEFB $04 ;;multiply rx*sin(a) - DEFB $E2 ;;get-mem-2 rx*sin(a), ry. - DEFB $E3 ;;get-mem-3 rx*sin(a), ry, cos(a). - DEFB $04 ;;multiply rx*sin(a), ry*cos(a). - DEFB $0F ;;addition rx*sin(a) + ry*cos(a). - DEFB $C2 ;;st-mem-2 new relative y rotated. - DEFB $02 ;;delete . - DEFB $38 ;;end-calc . +L2425: RST 28H ;; FP-CALC + DEFB $E1 ;;get-mem-1 rx. + DEFB $31 ;;duplicate rx, rx. + DEFB $E3 ;;get-mem-3 cos(a) + DEFB $04 ;;multiply rx, rx*cos(a). + DEFB $E2 ;;get-mem-2 rx, rx*cos(a), ry. + DEFB $E4 ;;get-mem-4 rx, rx*cos(a), ry, sin(a). + DEFB $04 ;;multiply rx, rx*cos(a), ry*sin(a). + DEFB $03 ;;subtract rx, rx*cos(a) - ry*sin(a) + DEFB $C1 ;;st-mem-1 rx, new relative x rotated. + DEFB $02 ;;delete rx. + + DEFB $E4 ;;get-mem-4 rx, sin(a). + DEFB $04 ;;multiply rx*sin(a) + DEFB $E2 ;;get-mem-2 rx*sin(a), ry. + DEFB $E3 ;;get-mem-3 rx*sin(a), ry, cos(a). + DEFB $04 ;;multiply rx*sin(a), ry*cos(a). + DEFB $0F ;;addition rx*sin(a) + ry*cos(a). + DEFB $C2 ;;st-mem-2 new relative y rotated. + DEFB $02 ;;delete . + DEFB $38 ;;end-calc . ; Note. the calculator stack actually holds tx, ty, ax, ay -; and the last absolute values of x and y +; and the last absolute values of x and y ; are now brought into play. ; ; Magically, the two new rotated coordinates rx and ry are all that we would ; require to draw a circle or arc - on paper! -; The Spectrum DRAW routine draws to the rounded x and y coordinate and so -; repetitions of values like 3.49 would mean that the fractional parts -; would be lost until eventually the draw coordinates might differ from the +; The Spectrum DRAW routine draws to the rounded x and y coordinate and so +; repetitions of values like 3.49 would mean that the fractional parts +; would be lost until eventually the draw coordinates might differ from the ; floating point values used above by several pixels. -; For this reason the accurate offsets calculated above are added to the -; accurate, absolute coordinates maintained in ax and ay and these new -; coordinates have the integer coordinates of the last plot position -; ( from System Variable COORDS ) subtracted from them to give the relative +; For this reason the accurate offsets calculated above are added to the +; accurate, absolute coordinates maintained in ax and ay and these new +; coordinates have the integer coordinates of the last plot position +; ( from System Variable COORDS ) subtracted from them to give the relative ; coordinates required by the DRAW routine. ; The mid entry point. @@ -396,49 +398,49 @@ L2439: PUSH BC ; Preserve the arc counter on the machine stack. ; Store the absolute ay in temporary variable mem-0 for the moment. - RST 28H ;; FP-CALC ax, ay. - DEFB $C0 ;;st-mem-0 ax, ay. - DEFB $02 ;;delete ax. + RST 28H ;; FP-CALC ax, ay. + DEFB $C0 ;;st-mem-0 ax, ay. + DEFB $02 ;;delete ax. ; Now add the fractional relative x coordinate to the fractional absolute ; x coordinate to obtain a new fractional x-coordinate. - DEFB $E1 ;;get-mem-1 ax, xr. - DEFB $0F ;;addition ax+xr (= new ax). - DEFB $31 ;;duplicate ax, ax. - DEFB $38 ;;end-calc ax, ax. + DEFB $E1 ;;get-mem-1 ax, xr. + DEFB $0F ;;addition ax+xr (= new ax). + DEFB $31 ;;duplicate ax, ax. + DEFB $38 ;;end-calc ax, ax. - LD A,(COORDS) ; COORDS-x last x (integer ix 0-255) - CALL L2D28 ; routine STACK-A + LD A,(COORDS) ; COORDS-x last x (integer ix 0-255) + CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC ax, ax, ix. - DEFB $03 ;;subtract ax, ax-ix = relative DRAW Dx. + RST 28H ;; FP-CALC ax, ax, ix. + DEFB $03 ;;subtract ax, ax-ix = relative DRAW Dx. ; Having calculated the x value for DRAW do the same for the y value. - DEFB $E0 ;;get-mem-0 ax, Dx, ay. - DEFB $E2 ;;get-mem-2 ax, Dx, ay, ry. - DEFB $0F ;;addition ax, Dx, ay+ry (= new ay). - DEFB $C0 ;;st-mem-0 ax, Dx, ay. - DEFB $01 ;;exchange ax, ay, Dx, - DEFB $E0 ;;get-mem-0 ax, ay, Dx, ay. - DEFB $38 ;;end-calc ax, ay, Dx, ay. + DEFB $E0 ;;get-mem-0 ax, Dx, ay. + DEFB $E2 ;;get-mem-2 ax, Dx, ay, ry. + DEFB $0F ;;addition ax, Dx, ay+ry (= new ay). + DEFB $C0 ;;st-mem-0 ax, Dx, ay. + DEFB $01 ;;exchange ax, ay, Dx, + DEFB $E0 ;;get-mem-0 ax, ay, Dx, ay. + DEFB $38 ;;end-calc ax, ay, Dx, ay. - LD A,(COORDS + 1) ; COORDS-y last y (integer iy 0-175) - CALL L2D28 ; routine STACK-A + LD A,(COORDS + 1) ; COORDS-y last y (integer iy 0-175) + CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC ax, ay, Dx, ay, iy. - DEFB $03 ;;subtract ax, ay, Dx, ay-iy ( = Dy). - DEFB $38 ;;end-calc ax, ay, Dx, Dy. + RST 28H ;; FP-CALC ax, ay, Dx, ay, iy. + DEFB $03 ;;subtract ax, ay, Dx, ay-iy ( = Dy). + DEFB $38 ;;end-calc ax, ay, Dx, Dy. - CALL L2477 ; Routine DRAW-LINE draws (Dx,Dy) relative to - ; the last pixel plotted leaving absolute x - ; and y on the calculator stack. - ; ax, ay. + CALL L2477 ; Routine DRAW-LINE draws (Dx,Dy) relative to + ; the last pixel plotted leaving absolute x + ; and y on the calculator stack. + ; ax, ay. - POP BC ; Restore the arc counter from the machine stack. + POP BC ; Restore the arc counter from the machine stack. - DJNZ L2425 ; Decrement and loop while > 0 to ARC-LOOP + DJNZ L2425 ; Decrement and loop while > 0 to ARC-LOOP ; ------------- ; THE 'ARC END' @@ -447,58 +449,60 @@ L2439: PUSH BC ; Preserve the arc counter on the machine stack. ; To recap the full calculator stack is tx, ty, ax, ay. ; Just as one would do if drawing the curve on paper, the final line would -; be drawn by joining the last point plotted to the initial start point -; in the case of a CIRCLE or to the calculated end point in the case of +; be drawn by joining the last point plotted to the initial start point +; in the case of a CIRCLE or to the calculated end point in the case of ; an ARC. ; The moving absolute values of x and y are no longer required and they ; can be deleted to expose the closing coordinates. ;; ARC-END L245F: RST 28H ;; FP-CALC tx, ty, ax, ay. - DEFB $02 ;;delete tx, ty, ax. - DEFB $02 ;;delete tx, ty. - DEFB $01 ;;exchange ty, tx. - DEFB $38 ;;end-calc ty, tx. + DEFB $02 ;;delete tx, ty, ax. + DEFB $02 ;;delete tx, ty. + DEFB $01 ;;exchange ty, tx. + DEFB $38 ;;end-calc ty, tx. ; First calculate the relative x coordinate to the end-point. - LD A,($5C7D) ; COORDS-x - CALL L2D28 ; routine STACK-A + LD A,($5C7D) ; COORDS-x + CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC ty, tx, coords_x. - DEFB $03 ;;subtract ty, rx. + RST 28H ;; FP-CALC ty, tx, coords_x. + DEFB $03 ;;subtract ty, rx. ; Next calculate the relative y coordinate to the end-point. - DEFB $01 ;;exchange rx, ty. - DEFB $38 ;;end-calc rx, ty. + DEFB $01 ;;exchange rx, ty. + DEFB $38 ;;end-calc rx, ty. - LD A,($5C7E) ; COORDS-y - CALL L2D28 ; routine STACK-A + LD A,($5C7E) ; COORDS-y + CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC rx, ty, coords_y - DEFB $03 ;;subtract rx, ry. - DEFB $38 ;;end-calc rx, ry. + RST 28H ;; FP-CALC rx, ty, coords_y + DEFB $03 ;;subtract rx, ry. + DEFB $38 ;;end-calc rx, ry. ; Finally draw the last straight line. L2477: - call STACK_TO_BC ;;Pops x, and y, and stores it in B, C - ld hl, (COORDS) ;;Calculates x2 and y2 in L, H + call STACK_TO_BC ;;Pops x, and y, and stores it in B, C + ld hl, (COORDS) ;;Calculates x2 and y2 in L, H - rl e ;; Rotate left to carry - ld a, c - jr nc, SUM_C - neg + rl e ;; Rotate left to carry + ld a, c + jr nc, SUM_C + neg SUM_C: - add a, l - ld l, a ;; X2 + add a, l + ld l, a ;; X2 - rl d ;; Low sign to carry - ld a, b - jr nc, SUM_B - neg + rl d ;; Low sign to carry + ld a, b + jr nc, SUM_B + neg SUM_B: - add a, h - ld h, a - jp __DRAW ;;forward to LINE-DRAW (Fastcalled) + add a, h + ld h, a + jp __DRAW ;;forward to LINE-DRAW (Fastcalled) + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/eq16.asm b/src/arch/zx48k/library-asm/eq16.asm index b8d75b2b3..0218e560b 100644 --- a/src/arch/zx48k/library-asm/eq16.asm +++ b/src/arch/zx48k/library-asm/eq16.asm @@ -1,8 +1,12 @@ + push namespace core + __EQ16: ; Test if 16bit values HL == DE - ; Returns result in A: 0 = False, FF = True - xor a ; Reset carry flag - sbc hl, de - ret nz - inc a - ret + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/eq32.asm b/src/arch/zx48k/library-asm/eq32.asm index 4c6e9af04..fb51892bd 100644 --- a/src/arch/zx48k/library-asm/eq32.asm +++ b/src/arch/zx48k/library-asm/eq32.asm @@ -1,25 +1,29 @@ + push namespace core + __EQ32: ; Test if 32bit value HLDE equals top of the stack - ; Returns result in A: 0 = False, FF = True - exx - pop bc ; Return address - exx + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part - xor a ; Reset carry flag - pop bc - sbc hl, bc ; Low part - ex de, hl - pop bc - sbc hl, bc ; High part + exx + push bc ; CALLEE + exx - exx - push bc ; CALLEE - exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret - ld a, h - or l - or d - or e ; a = 0 and Z flag set only if HLDE = 0 - ld a, 1 - ret z - xor a - ret + pop namespace diff --git a/src/arch/zx48k/library-asm/eqf.asm b/src/arch/zx48k/library-asm/eqf.asm index c31776ff0..4e8ebfc82 100644 --- a/src/arch/zx48k/library-asm/eqf.asm +++ b/src/arch/zx48k/library-asm/eqf.asm @@ -13,15 +13,19 @@ ; ------------------------------------------------------------- + push namespace core + __EQF: ; A = B - call __FPSTACK_PUSH2 - - ; ------------- ROM NOS-EQL - ld b, 0Eh ; For comparison operators, OP must be in B also - rst 28h - defb 0Eh - defb 38h; ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/error.asm b/src/arch/zx48k/library-asm/error.asm index 952cac736..e603d5477 100644 --- a/src/arch/zx48k/library-asm/error.asm +++ b/src/arch/zx48k/library-asm/error.asm @@ -1,6 +1,8 @@ ; Simple error control routines ; vim:ts=4:et: + push namespace core + ERR_NR EQU 23610 ; Error code system variable @@ -19,7 +21,7 @@ ERROR_NumberTooBig EQU 5 ERROR_InvalidArg EQU 9 ERROR_IntOutOfRange EQU 10 ERROR_NonsenseInBasic EQU 11 -ERROR_InvalidFileName EQU 14 +ERROR_InvalidFileName EQU 14 ERROR_InvalidColour EQU 19 ERROR_BreakIntoProgram EQU 20 ERROR_TapeLoadingErr EQU 26 @@ -38,3 +40,5 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/exp.asm b/src/arch/zx48k/library-asm/exp.asm index 3ed1a56d4..d1a439e2f 100644 --- a/src/arch/zx48k/library-asm/exp.asm +++ b/src/arch/zx48k/library-asm/exp.asm @@ -1,11 +1,15 @@ #include once + push namespace core + EXP: ; Computes e^n using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 26h ; E^n + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 26h ; E^n - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/f16tofreg.asm b/src/arch/zx48k/library-asm/f16tofreg.asm index 1a3699963..97ab00997 100644 --- a/src/arch/zx48k/library-asm/f16tofreg.asm +++ b/src/arch/zx48k/library-asm/f16tofreg.asm @@ -1,26 +1,28 @@ #include once #include once + push namespace core + __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign + ld a, d + or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e @@ -30,19 +32,21 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl + push de + push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/flash.asm b/src/arch/zx48k/library-asm/flash.asm index 6e009a4e8..507ab4980 100644 --- a/src/arch/zx48k/library-asm/flash.asm +++ b/src/arch/zx48k/library-asm/flash.asm @@ -3,41 +3,45 @@ #include once + push namespace core + FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/free.asm b/src/arch/zx48k/library-asm/free.asm index 4eddb3a49..883e75b8d 100644 --- a/src/arch/zx48k/library-asm/free.asm +++ b/src/arch/zx48k/library-asm/free.asm @@ -1,6 +1,6 @@ ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa -; (a.k.a. Boriel) +; (a.k.a. Boriel) ; http://www.boriel.com ; ; This ASM library is licensed under the BSD license @@ -13,20 +13,20 @@ ; The heap is implemented as a linked list of free blocks. ; Each free block contains this info: -; -; +----------------+ <-- HEAP START +; +; +----------------+ <-- HEAP START ; | Size (2 bytes) | ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK ; +----------------+ ; | Next (2 bytes) |---+ -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | <-- If Size > 4, then this contains (size - 4) bytes ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ @@ -35,14 +35,14 @@ ; | (0 if Size = 4)| | ; +----------------+ | ; | <-- This zone is in use (Already allocated) -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Next (2 bytes) |--> NULL => END OF LIST ; | 0 = NULL | ; +----------------+ @@ -59,7 +59,7 @@ ; MEMORY MANAGER ; -; This library must be initialized calling __MEM_INIT with +; This library must be initialized calling __MEM_INIT with ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. @@ -76,114 +76,118 @@ ; is done ; --------------------------------------------------------------------- + push namespace core + MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC + ; HL DE BC & AF modified + PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer + ld a, h + or l + ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr + inc hl + inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - - ld b, h - ld c, l ; BC = Total Length - - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - - ENDP + push hl ; Saves it for later + ex de, hl + + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + + ld b, h + ld c, l ; BC = Total Length + + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/ftof16reg.asm b/src/arch/zx48k/library-asm/ftof16reg.asm index 58791d7e7..b1b19f9fb 100644 --- a/src/arch/zx48k/library-asm/ftof16reg.asm +++ b/src/arch/zx48k/library-asm/ftof16reg.asm @@ -1,42 +1,46 @@ #include once + push namespace core + __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - - push hl ; Stores it for later (Contains sign in H, exponent in L) + ret z ; Return if ZERO + + push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc + push de + push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx + set 7, c ; Highest mantissa bit is always 1 + exx + + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace diff --git a/src/arch/zx48k/library-asm/ftou32reg.asm b/src/arch/zx48k/library-asm/ftou32reg.asm index 0cdfaddbe..ab84e3072 100644 --- a/src/arch/zx48k/library-asm/ftou32reg.asm +++ b/src/arch/zx48k/library-asm/ftou32reg.asm @@ -1,68 +1,70 @@ #include once + push namespace core + __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE + LOCAL __IS_FLOAT + LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) + ld h, e + push hl ; Stores it for later (Contains Sign in H) - push de - push bc + push de + push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx + set 7, c ; Highest mantissa bit is always 1 + exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d + rl l + rl h + rl e + rl d - djnz __FTOU32REG_LOOP + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + + ret __NEGATE: exx @@ -80,11 +82,13 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/gef.asm b/src/arch/zx48k/library-asm/gef.asm index 7fb40603b..58088672a 100644 --- a/src/arch/zx48k/library-asm/gef.asm +++ b/src/arch/zx48k/library-asm/gef.asm @@ -13,15 +13,19 @@ ; ------------------------------------------------------------- + push namespace core + __GEF: ; A >= B - call __FPSTACK_PUSH2 ; Enters B, A - - ; ------------- ROM NO-LESS - ld b, 09h ; B =< A - rst 28h - defb 09h - defb 38h ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; Enters B, A + + ; ------------- ROM NO-LESS + ld b, 09h ; B =< A + rst 28h + defb 09h + defb 38h ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/gtf.asm b/src/arch/zx48k/library-asm/gtf.asm index 05bbdac9a..4ef1d885a 100644 --- a/src/arch/zx48k/library-asm/gtf.asm +++ b/src/arch/zx48k/library-asm/gtf.asm @@ -12,15 +12,19 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __GTF: ; A > B - call __FPSTACK_PUSH2 ; ENTERS B, A - - ; ------------- ROM NOS-GRTR - ld b, 0Dh ; B < A - rst 28h - defb 0Dh ; B < A - defb 38h; ; END CALC - - call __FPSTACK_POP - jp __FTOU8; Convert to 8 bits + call __FPSTACK_PUSH2 ; ENTERS B, A + + ; ------------- ROM NOS-GRTR + ld b, 0Dh ; B < A + rst 28h + defb 0Dh ; B < A + defb 38h; ; END CALC + + call __FPSTACK_POP + jp __FTOU8; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/heapinit.asm b/src/arch/zx48k/library-asm/heapinit.asm index 62d39f0f3..6a1df5bae 100644 --- a/src/arch/zx48k/library-asm/heapinit.asm +++ b/src/arch/zx48k/library-asm/heapinit.asm @@ -1,6 +1,6 @@ ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa -; (a.k.a. Boriel) +; (a.k.a. Boriel) ; http://www.boriel.com ; ; This ASM library is licensed under the BSD license @@ -13,20 +13,20 @@ ; The heap is implemented as a linked list of free blocks. ; Each free block contains this info: -; -; +----------------+ <-- HEAP START +; +; +----------------+ <-- HEAP START ; | Size (2 bytes) | ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK ; +----------------+ ; | Next (2 bytes) |---+ -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | <-- If Size > 4, then this contains (size - 4) bytes ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ @@ -35,14 +35,14 @@ ; | (0 if Size = 4)| | ; +----------------+ | ; | <-- This zone is in use (Already allocated) -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Next (2 bytes) |--> NULL => END OF LIST ; | 0 = NULL | ; +----------------+ @@ -59,67 +59,71 @@ ; MEMORY MANAGER ; -; This library must be initialized calling __MEM_INIT with +; This library must be initialized calling __MEM_INIT with ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#init "__MEM_INIT" +#init "core.__MEM_INIT" ; --------------------------------------------------------------------- ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core + __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- -; __MEM_INIT2 initalizes this library +; __MEM_INIT2 initalizes this library ; Parameters: ; HL : Memory address of 1st byte of the memory heap ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- -__MEM_INIT2: - ; HL as TOP - PROC - - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - - ENDP +__MEM_INIT2: + ; HL as TOP + PROC + + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/iload32.asm b/src/arch/zx48k/library-asm/iload32.asm index 3943adfbe..a647bcdc9 100644 --- a/src/arch/zx48k/library-asm/iload32.asm +++ b/src/arch/zx48k/library-asm/iload32.asm @@ -3,15 +3,19 @@ ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core + __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/iloadf.asm b/src/arch/zx48k/library-asm/iloadf.asm index 0e82a5a47..b425e3588 100644 --- a/src/arch/zx48k/library-asm/iloadf.asm +++ b/src/arch/zx48k/library-asm/iloadf.asm @@ -3,6 +3,8 @@ ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core + __ILOADF: ld a, (hl) inc hl @@ -15,14 +17,16 @@ __ILOADF: ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/in_screen.asm b/src/arch/zx48k/library-asm/in_screen.asm index 4fd033a26..23eb2a222 100644 --- a/src/arch/zx48k/library-asm/in_screen.asm +++ b/src/arch/zx48k/library-asm/in_screen.asm @@ -1,29 +1,33 @@ #include once #include once + push namespace core + __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - - PROC - LOCAL __IN_SCREEN_ERR - - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + + PROC + LOCAL __IN_SCREEN_ERR + + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/ink.asm b/src/arch/zx48k/library-asm/ink.asm index 5edd031d1..89763d0ca 100644 --- a/src/arch/zx48k/library-asm/ink.asm +++ b/src/arch/zx48k/library-asm/ink.asm @@ -3,41 +3,45 @@ #include once + push namespace core + INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 - ld de, ATTR_P + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 + cp 8 + jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK + ld de, ATTR_T + jp __SET_INK + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/inkey.asm b/src/arch/zx48k/library-asm/inkey.asm index 3f73b5578..99a6c446e 100644 --- a/src/arch/zx48k/library-asm/inkey.asm +++ b/src/arch/zx48k/library-asm/inkey.asm @@ -5,56 +5,60 @@ #include once + push namespace core + INKEY: - PROC - LOCAL __EMPTY_INKEY - LOCAL KEY_SCAN - LOCAL KEY_TEST - LOCAL KEY_CODE - - ld bc, 3 ; 1 char length string - call __MEM_ALLOC - - ld a, h - or l - ret z ; Return if NULL (No memory) - - push hl ; Saves memory pointer - - call KEY_SCAN - jp nz, __EMPTY_INKEY - - call KEY_TEST - jp nc, __EMPTY_INKEY - - dec d ; D is expected to be FLAGS so set bit 3 $FF - ; 'L' Mode so no keywords. - ld e, a ; main key to A - ; C is MODE 0 'KLC' from above still. - call KEY_CODE ; routine K-DECODE - pop hl - - ld (hl), 1 - inc hl - ld (hl), 0 - inc hl - ld (hl), a - dec hl - dec hl ; HL Points to string result - ret + PROC + LOCAL __EMPTY_INKEY + LOCAL KEY_SCAN + LOCAL KEY_TEST + LOCAL KEY_CODE + + ld bc, 3 ; 1 char length string + call __MEM_ALLOC + + ld a, h + or l + ret z ; Return if NULL (No memory) + + push hl ; Saves memory pointer + + call KEY_SCAN + jp nz, __EMPTY_INKEY + + call KEY_TEST + jp nc, __EMPTY_INKEY + + dec d ; D is expected to be FLAGS so set bit 3 $FF + ; 'L' Mode so no keywords. + ld e, a ; main key to A + ; C is MODE 0 'KLC' from above still. + call KEY_CODE ; routine K-DECODE + pop hl + + ld (hl), 1 + inc hl + ld (hl), 0 + inc hl + ld (hl), a + dec hl + dec hl ; HL Points to string result + ret __EMPTY_INKEY: - pop hl - xor a - ld (hl), a - inc hl - ld (hl), a - dec hl - ret + pop hl + xor a + ld (hl), a + inc hl + ld (hl), a + dec hl + ret KEY_SCAN EQU 028Eh KEY_TEST EQU 031Eh KEY_CODE EQU 0333h - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/inverse.asm b/src/arch/zx48k/library-asm/inverse.asm index 2eaf22eb3..974a0c5bc 100644 --- a/src/arch/zx48k/library-asm/inverse.asm +++ b/src/arch/zx48k/library-asm/inverse.asm @@ -3,29 +3,33 @@ #include once + push namespace core + INVERSE: - PROC - - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/istore16.asm b/src/arch/zx48k/library-asm/istore16.asm index 716089d78..e2a918c24 100644 --- a/src/arch/zx48k/library-asm/istore16.asm +++ b/src/arch/zx48k/library-asm/istore16.asm @@ -1,16 +1,20 @@ + push namespace core + __PISTORE16: ; stores an integer in hl into address IX + BC; Destroys DE - ex de, hl - push ix - pop hl - add hl, bc + ex de, hl + push ix + pop hl + add hl, bc __ISTORE16: ; Load address at hl, and stores E,D integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ld (hl), e - inc hl - ld (hl), d - ret - + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ld (hl), e + inc hl + ld (hl), d + ret + + pop namespace + diff --git a/src/arch/zx48k/library-asm/italic.asm b/src/arch/zx48k/library-asm/italic.asm index 79b5ebbbe..5d24dae13 100644 --- a/src/arch/zx48k/library-asm/italic.asm +++ b/src/arch/zx48k/library-asm/italic.asm @@ -2,31 +2,35 @@ ; Parameter: ITALIC flag in bit 0 of A register #include once + push namespace core + ITALIC: - PROC + PROC - and 1 + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/lddede.asm b/src/arch/zx48k/library-asm/lddede.asm index c2ae75bd7..4718f2fcf 100644 --- a/src/arch/zx48k/library-asm/lddede.asm +++ b/src/arch/zx48k/library-asm/lddede.asm @@ -1,13 +1,17 @@ ; Loads DE into DE ; Modifies C register -; There is a routine similar to this one +; There is a routine similar to this one ; at ROM address L2AEE + push namespace core + __LOAD_DE_DE: - ex de, hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c - ex de, hl - ret + ex de, hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c + ex de, hl + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/lef.asm b/src/arch/zx48k/library-asm/lef.asm index 294fb2388..30fecdad0 100644 --- a/src/arch/zx48k/library-asm/lef.asm +++ b/src/arch/zx48k/library-asm/lef.asm @@ -12,15 +12,19 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __LEF: ; A <= B - call __FPSTACK_PUSH2 ; B, A - - ; ------------- ROM NO-L-EQL - ld b, 0Ah ; B => A - rst 28h - defb 0Ah ; B => A - defb 38h; ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; B, A + + ; ------------- ROM NO-L-EQL + ld b, 0Ah ; B => A + rst 28h + defb 0Ah ; B => A + defb 38h; ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/lei16.asm b/src/arch/zx48k/library-asm/lei16.asm index 50852509e..60d5cb65a 100644 --- a/src/arch/zx48k/library-asm/lei16.asm +++ b/src/arch/zx48k/library-asm/lei16.asm @@ -1,3 +1,5 @@ + push namespace core + __LEI16: PROC LOCAL checkParity @@ -14,3 +16,5 @@ checkParity: inc a ; True ret ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/lei32.asm b/src/arch/zx48k/library-asm/lei32.asm index 4a7db3acb..a53db51ba 100644 --- a/src/arch/zx48k/library-asm/lei32.asm +++ b/src/arch/zx48k/library-asm/lei32.asm @@ -1,6 +1,8 @@ #include once + push namespace core + __LEI32: ; Test 32 bit values Top of the stack <= HL,DE PROC LOCAL checkParity @@ -32,3 +34,5 @@ checkParity: inc a ; True ret ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/lei8.asm b/src/arch/zx48k/library-asm/lei8.asm index 6860230d3..6480a963b 100644 --- a/src/arch/zx48k/library-asm/lei8.asm +++ b/src/arch/zx48k/library-asm/lei8.asm @@ -1,5 +1,7 @@ + push namespace core + __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -19,3 +21,5 @@ checkParity: inc a ; True ret ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/letsubstr.asm b/src/arch/zx48k/library-asm/letsubstr.asm index f71d6b510..6ce63a51f 100644 --- a/src/arch/zx48k/library-asm/letsubstr.asm +++ b/src/arch/zx48k/library-asm/letsubstr.asm @@ -1,7 +1,7 @@ ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" ; HL = Start of string ; TOP of the stack -> p1 (16 bit, unsigned) -; TOP -1 of the stack -> p0 register +; TOP -1 of the stack -> p0 register ; TOP -2 Flag (popped out in A register) ; A Register => 0 if HL is not freed from memory ; => Not 0 if HL must be freed from memory on exit @@ -9,146 +9,150 @@ #include once + push namespace core + __LETSUBSTR: - PROC - - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - - pop af ; Flag - ex af, af' ; Save it for later - - pop de ; B$ - - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - - ld a, h - or l - jp z, __FREE_STR ; Return if null - - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - - or a - sbc hl, bc ; P0 >= String length? - exx - - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - - exx - add hl, bc ; Add it back - - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen - + PROC + + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + + pop af ; Flag + ex af, af' ; Save it for later + + pop de ; B$ + + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + + ld a, h + or l + jp z, __FREE_STR ; Return if null + + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + + or a + sbc hl, bc ; P0 >= String length? + exx + + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + + exx + add hl, bc ; Add it back + + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen + __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de + ; BC = start of char to copy + push de - push bc - exx - pop bc + push bc + exx + pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) + add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e + ld b, d ; Length of string + ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write - ldir + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - - ld c, (hl) - inc hl - ld b, (hl) - inc hl - - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + + ld c, (hl) + inc hl + ld b, (hl) + inc hl + + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/load.asm b/src/arch/zx48k/library-asm/load.asm index 1209fe031..0da9db990 100644 --- a/src/arch/zx48k/library-asm/load.asm +++ b/src/arch/zx48k/library-asm/load.asm @@ -4,6 +4,8 @@ # include once #endif + push namespace core + LOAD_CODE: ; This function will implement the LOAD CODE Routine ; Parameters in the stack are HL => String with LOAD name @@ -13,7 +15,7 @@ LOAD_CODE: ; A = 1 => LOAD 0 => Verify PROC - + LOCAL LOAD_CONT, LOAD_CONT2, LOAD_CONT3 LOCAL LD_BYTES LOCAL LOAD_HEADER @@ -29,8 +31,8 @@ LOAD_CODE: MEM0 EQU 5C92h ; Temporary memory buffer HEAD1 EQU MEM0 + 8 ; Uses CALC Mem for temporary storage - ; Must skip first 8 bytes used by - ; PRINT routine + ; Must skip first 8 bytes used by + ; PRINT routine TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage TMP_SP EQU TMP_HEADER + 2 ; Temporary SP storage @@ -39,13 +41,13 @@ LD_BYTES EQU 0556h ; ROM Routine LD-BYTES #endif TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG - + pop hl ; Return address pop af ; A = 1 => LOAD; A = 0 => VERIFY pop bc ; data length in bytes pop de ; address start ex (sp), hl ; CALLE => now hl = String - + __LOAD_CODE: ; INLINE version push ix ; saves IX ld (TMP_FLAG), a ; Stores verify/load flag @@ -67,7 +69,7 @@ __LOAD_CODE: ; INLINE version ld b, h ld c, l jr z, LOAD_HEADER ; NULL STRING => LOAD "" - + ld c, (hl) inc hl ld b, (hl) @@ -87,7 +89,7 @@ __LOAD_CODE: ; INLINE version ldir pop bc pop hl - + LOAD_HEADER: ex de, hl ; Saves HL in DE ld hl, 10 @@ -96,7 +98,7 @@ LOAD_HEADER: ex de, hl ; Retrieve HL jr nc, LOAD_CONT ; Ok BC <= 10 ld bc, 10 ; BC at most 10 chars - + LOAD_CONT: ld de, HEAD1 + 1 ldir ; Copy String block NAME in header @@ -123,25 +125,25 @@ LD_LOOK_H: ld de, 17 ; seventeen bytes xor a ; reset zero flag scf ; set carry flag - + call LD_BYTES ; routine LD-BYTES loads a header from tape - ; to second descriptor. + ; to second descriptor. pop ix ; restore IX jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found. ld c, 80h ; C has bit 7 set to indicate header type mismatch as - ; a default startpoint. + ; a default startpoint. ld a, (ix + 0) ; compare loaded type cp 3 ; with expected bytes header jr nz, LD_TYPE ; forward to LD-TYPE with mis-match. ld c, -10 ; set C to minus ten - will count characters - ; up to zero. + ; up to zero. LD_TYPE: cp 4 ; check if type in acceptable range 0 - 3. jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over. - ; else A indicates type 0-3. + ; else A indicates type 0-3. #ifndef HIDE_LOAD_MSG call PRINT_TAPE_MESSAGES; Print tape msg #endif @@ -149,9 +151,9 @@ LD_TYPE: ld hl, HEAD1 + 1 ; point HL to 1st descriptor. ld de, (TMP_HEADER) ; point DE to 2nd descriptor. ld b, 10 ; the count will be ten characters for the - ; filename. + ; filename. - ld a, (hl) ; fetch first character and test for + ld a, (hl) ; fetch first character and test for inc a ; value 255. jr nz, LD_NAME ; forward to LD-NAME if not the wildcard. @@ -160,7 +162,7 @@ LD_TYPE: ; bit 7 of C will not alter from state set here. ld a, c ; transfer $F6 or $80 to A - add a, b ; add 10 + add a, b ; add 10 ld c, a ; place result, zero or -118, in C. ; At this point we have either a type mismatch, a wildcard match or ten @@ -210,7 +212,7 @@ VR_CONTROL: ld l, a or h ; check length of old for zero. (Carry reset) jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified - ; e.g. LOAD "x" CODE + ; e.g. LOAD "x" CODE sbc hl, de jr nz, LOAD_ERROR ; Lengths don't match @@ -232,7 +234,7 @@ VR_CONT_2: ld a, (TMP_FLAG) ; load verify/load flag sra a ; shift bit 0 to Carry (1 => Load, 0 = Verify), A = 0 - dec a ; a = 0xFF (Data) + dec a ; a = 0xFF (Data) call LD_BYTES jr c, LOAD_END ; if carry, load/verification was ok @@ -287,7 +289,7 @@ PRINT_TAPE_MESSAGES: LOCAL PRINT_TAPE_MSG ; Print tape messages according to A value - ; Each message starts with a carriage return and + ; Each message starts with a carriage return and ; ends with last char having its bit 7 set ; A = 0 => '\nProgram: ' @@ -300,7 +302,7 @@ PRINT_TAPE_MESSAGES: ld hl, 09C0h ; address base of last 4 tape messages ld b, a inc b ; avoid 256-loop if b == 0 - ld a, 0Dh ; Msg start mark + ld a, 0Dh ; Msg start mark ; skip memory bytes looking for next tape msg entry ; each msg ends when 0Dh is fond @@ -308,12 +310,12 @@ LOOK_NEXT_TAPE_MSG: inc hl ; Point to next char cp (hl) ; Is it 0Dh? jr nz, LOOK_NEXT_TAPE_MSG - ; Ok next message found + ; Ok next message found djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip PRINT_TAPE_MSG: - ; Ok. This will print bytes after (HL) - ; until one of them has bit 7 set + ; Ok. This will print bytes after (HL) + ; until one of them has bit 7 set ld a, (hl) and 7Fh ; Clear bit 7 of A call __PRINTCHAR @@ -325,7 +327,9 @@ PRINT_TAPE_MSG: pop bc ret - + ENDP #endif + + pop namespace diff --git a/src/arch/zx48k/library-asm/loadstr.asm b/src/arch/zx48k/library-asm/loadstr.asm index 2a9542d4a..168bf72d8 100644 --- a/src/arch/zx48k/library-asm/loadstr.asm +++ b/src/arch/zx48k/library-asm/loadstr.asm @@ -4,40 +4,44 @@ ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core + __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - - ld a, h - or l - ret z ; Return if NULL (No memory) - - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + + ld a, h + or l + ret z ; Return if NULL (No memory) + + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/logn.asm b/src/arch/zx48k/library-asm/logn.asm index b6dfcadd3..bd5896ef9 100644 --- a/src/arch/zx48k/library-asm/logn.asm +++ b/src/arch/zx48k/library-asm/logn.asm @@ -1,11 +1,15 @@ #include once + push namespace core + LN: ; Computes Ln(x) using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 20h ; 25h + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 20h ; 25h - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/ltf.asm b/src/arch/zx48k/library-asm/ltf.asm index 230ad1e4e..8134ddc57 100644 --- a/src/arch/zx48k/library-asm/ltf.asm +++ b/src/arch/zx48k/library-asm/ltf.asm @@ -12,15 +12,19 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __LTF: ; A < B - call __FPSTACK_PUSH2 ; Enters B, A - - ; ------------- ROM NOS-LESS - ld b, 0Ch ; A > B (Operands stack-reversed) - rst 28h - defb 0Ch; ; A > B - defb 38h; ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; Enters B, A + + ; ------------- ROM NOS-LESS + ld b, 0Ch ; A > B (Operands stack-reversed) + rst 28h + defb 0Ch; ; A > B + defb 38h; ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/lti16.asm b/src/arch/zx48k/library-asm/lti16.asm index 0d21c93d4..3b15666ca 100644 --- a/src/arch/zx48k/library-asm/lti16.asm +++ b/src/arch/zx48k/library-asm/lti16.asm @@ -1,7 +1,9 @@ #include once + push namespace core + __LTI16: ; Test 8 bit values HL < DE - ; Returns result in A: 0 = False, !0 = True + ; Returns result in A: 0 = False, !0 = True PROC LOCAL checkParity or a @@ -15,3 +17,5 @@ checkParity: inc a ; True ret ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/lti32.asm b/src/arch/zx48k/library-asm/lti32.asm index 4b830dfb7..f49ce48b9 100644 --- a/src/arch/zx48k/library-asm/lti32.asm +++ b/src/arch/zx48k/library-asm/lti32.asm @@ -1,6 +1,8 @@ #include once + push namespace core + __LTI32: ; Test 32 bit values in Top of the stack < HLDE PROC LOCAL checkParity @@ -23,3 +25,5 @@ checkParity: inc a ; True ret ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/memcopy.asm b/src/arch/zx48k/library-asm/memcopy.asm index d098cddc4..ab4816ea0 100644 --- a/src/arch/zx48k/library-asm/memcopy.asm +++ b/src/arch/zx48k/library-asm/memcopy.asm @@ -1,6 +1,6 @@ ; ---------------------------------------------------------------- ; This file is released under the MIT License -; +; ; Copyleft (k) 2008 ; by Jose Rodriguez-Rosa (a.k.a. Boriel) ; @@ -14,23 +14,25 @@ ; DE => Start of destiny block ; BC => Block length + push namespace core + __MEMCPY: PROC LOCAL __MEMCPY2 push hl - add hl, bc ; addr of last source block byte + 1 + add hl, bc ; addr of last source block byte + 1 or a sbc hl, de ; checks if DE > HL + BC pop hl ; recovers HL. If carry => DE > HL + BC (no overlap) jr c, __MEMCPY2 - ; Now checks if DE <= HL + ; Now checks if DE <= HL - sbc hl, de ; Even if overlap, if DE < HL then we can LDIR safely - add hl, de - jr nc, __MEMCPY2 + sbc hl, de ; Even if overlap, if DE < HL then we can LDIR safely + add hl, de + jr nc, __MEMCPY2 dec bc add hl, bc @@ -46,4 +48,6 @@ __MEMCPY2: ldir ret - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/modf.asm b/src/arch/zx48k/library-asm/modf.asm index edee62c28..7ff2b2e94 100644 --- a/src/arch/zx48k/library-asm/modf.asm +++ b/src/arch/zx48k/library-asm/modf.asm @@ -10,14 +10,18 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __MODF: ; MODULO - call __FPSTACK_PUSH2 ; Enters B, A - - ; ------------- ROM DIV - rst 28h - defb 01h ; EXCHANGE - defb 32h ; MOD - defb 38h; ; END CALC - - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; Enters B, A + + ; ------------- ROM DIV + rst 28h + defb 01h ; EXCHANGE + defb 32h ; MOD + defb 38h; ; END CALC + + jp __FPSTACK_POP + + pop namespace diff --git a/src/arch/zx48k/library-asm/modf16.asm b/src/arch/zx48k/library-asm/modf16.asm index 041d4eb41..774444bd7 100644 --- a/src/arch/zx48k/library-asm/modf16.asm +++ b/src/arch/zx48k/library-asm/modf16.asm @@ -3,10 +3,12 @@ #include once #include once + push namespace core + __MODF16: - ; 16.16 Fixed point Division (signed) - ; DE.HL = Divisor, Stack Top = Divider - ; A = Dividend, B = Divisor => A % B + ; 16.16 Fixed point Division (signed) + ; DE.HL = Divisor, Stack Top = Divider + ; A = Dividend, B = Divisor => A % B PROC LOCAL TEMP @@ -15,23 +17,25 @@ TEMP EQU 23698 ; MEMBOT pop bc ; ret addr ld (TEMP), bc ; stores it on MEMBOT temporarily - ld (TEMP + 2), hl ; stores HP of divider - ld (TEMP + 4), de ; stores DE of divider + ld (TEMP + 2), hl ; stores HP of divider + ld (TEMP + 4), de ; stores DE of divider call __DIVF16 - rlc d ; Sign into carry - sbc a, a ; a register = -1 sgn(DE), or 0 - ld d, a - ld e, a ; DE = 0 if it was positive or 0; -1 if it was negative - - ld bc, (TEMP + 4) ; Pushes original divider into the stack - push bc - ld bc, (TEMP + 2) - push bc - + rlc d ; Sign into carry + sbc a, a ; a register = -1 sgn(DE), or 0 + ld d, a + ld e, a ; DE = 0 if it was positive or 0; -1 if it was negative + + ld bc, (TEMP + 4) ; Pushes original divider into the stack + push bc + ld bc, (TEMP + 2) + push bc + ld bc, (TEMP) ; recovers return address push bc jp __MULF16 ; multiplies and return from there ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/mul16.asm b/src/arch/zx48k/library-asm/mul16.asm index 2dbe29e24..2755ec238 100644 --- a/src/arch/zx48k/library-asm/mul16.asm +++ b/src/arch/zx48k/library-asm/mul16.asm @@ -1,32 +1,36 @@ + push namespace core + __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned + ; Works for both signed and unsigned + + PROC - PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP + djnz __MUL16LOOP + + ret ; Result in hl (16 lower bits) - ret ; Result in hl (16 lower bits) + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/mul32.asm b/src/arch/zx48k/library-asm/mul32.asm index d98d55e70..9f259f508 100644 --- a/src/arch/zx48k/library-asm/mul32.asm +++ b/src/arch/zx48k/library-asm/mul32.asm @@ -1,23 +1,28 @@ #include once <_mul32.asm> -__MUL32: ; multiplies 32 bit un/signed integer. - ; First operand stored in DEHL, and 2nd onto stack - ; Lowest part of 2nd operand on top of the stack - ; returns the result in DE.HL - exx - pop hl ; Return ADDRESS - pop de ; Low part - ex (sp), hl ; CALLEE -> HL = High part - ex de, hl - call __MUL32_64START + push namespace core + +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) - exx - push bc - exx - pop de - ld h, a - ld l, c - ret + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/mul8.asm b/src/arch/zx48k/library-asm/mul8.asm index ded5ed8bf..5b168a0cd 100644 --- a/src/arch/zx48k/library-asm/mul8.asm +++ b/src/arch/zx48k/library-asm/mul8.asm @@ -1,19 +1,21 @@ + push namespace core + __MUL8: ; Performs 8bit x 8bit multiplication - PROC + PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 ;; ld l, d -;; -;; sla h +;; +;; sla h ;; jr nc, __MUL8A ;; ld l, e ;; @@ -45,7 +47,9 @@ __MUL8LOOP: __MUL8B: djnz __MUL8LOOP - - ret ; result = HL - ENDP + + ret ; result = HL + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/mulf.asm b/src/arch/zx48k/library-asm/mulf.asm index e361ce85a..4999387f3 100644 --- a/src/arch/zx48k/library-asm/mulf.asm +++ b/src/arch/zx48k/library-asm/mulf.asm @@ -9,13 +9,17 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __MULF: ; Multiplication - call __FPSTACK_PUSH2 - - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC + call __FPSTACK_PUSH2 + + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/mulf16.asm b/src/arch/zx48k/library-asm/mulf16.asm index 576d68525..42d4d83c7 100644 --- a/src/arch/zx48k/library-asm/mulf16.asm +++ b/src/arch/zx48k/library-asm/mulf16.asm @@ -1,43 +1,47 @@ #include once #include once <_mul32.asm> -__MULF16: ; - ld a, d ; load sgn into a - ex af, af' ; saves it - call __ABS32 ; convert to positive + push namespace core - exx - pop hl ; Return address - pop de ; Low part - ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address - ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) +__MULF16: ; + ld a, d ; load sgn into a + ex af, af' ; saves it + call __ABS32 ; convert to positive - ex af, af' - xor d ; A register contains resulting sgn - ex af, af' - call __ABS32 ; convert to positive + exx + pop hl ; Return address + pop de ; Low part + ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address + ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) - call __MUL32_64START + ex af, af' + xor d ; A register contains resulting sgn + ex af, af' + call __ABS32 ; convert to positive + + call __MUL32_64START ; rounding (was not included in zx81) __ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 - ; result returned in dehl - ; input in h'l'hlb'c'ac - sla a ; result bit 47 to carry - exx - ld hl,0 ; ld does not change carry - adc hl,bc ; hl = hl + 0 + carry - push hl - - exx - ld bc,0 - adc hl,bc ; hl = hl + 0 + carry - ex de, hl - pop hl ; rounded result in de.hl - - ex af, af' ; recovers result sign - or a - jp m, __NEG32 ; if negative, negates it - - ret - + ; result returned in dehl + ; input in h'l'hlb'c'ac + sla a ; result bit 47 to carry + exx + ld hl,0 ; ld does not change carry + adc hl,bc ; hl = hl + 0 + carry + push hl + + exx + ld bc,0 + adc hl,bc ; hl = hl + 0 + carry + ex de, hl + pop hl ; rounded result in de.hl + + ex af, af' ; recovers result sign + or a + jp m, __NEG32 ; if negative, negates it + + ret + + pop namespace + diff --git a/src/arch/zx48k/library-asm/nef.asm b/src/arch/zx48k/library-asm/nef.asm index acc05e85c..765ddcaa3 100644 --- a/src/arch/zx48k/library-asm/nef.asm +++ b/src/arch/zx48k/library-asm/nef.asm @@ -12,15 +12,19 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __NEF: ; A <> B - call __FPSTACK_PUSH2 ; Enters B, A - - ; ------------- ROM NOS-NEQ - ld b, 0Bh - rst 28h - defb 0Bh - defb 38h ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; Enters B, A + + ; ------------- ROM NOS-NEQ + ld b, 0Bh + rst 28h + defb 0Bh + defb 38h ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/neg16.asm b/src/arch/zx48k/library-asm/neg16.asm index 90e05d62c..b21f8ea92 100644 --- a/src/arch/zx48k/library-asm/neg16.asm +++ b/src/arch/zx48k/library-asm/neg16.asm @@ -1,15 +1,19 @@ ; Negates HL value (16 bit) + push namespace core + __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/neg32.asm b/src/arch/zx48k/library-asm/neg32.asm index 1757224da..ce7932ee4 100644 --- a/src/arch/zx48k/library-asm/neg32.asm +++ b/src/arch/zx48k/library-asm/neg32.asm @@ -1,30 +1,34 @@ + push namespace core + __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - - ld a, h - cpl - ld h, a - - ld a, e - cpl - ld e, a - - ld a, d - cpl - ld d, a - - inc l - ret nz - - inc h - ret nz - - inc de - ret + ld a, l + cpl + ld l, a + + ld a, h + cpl + ld h, a + + ld a, e + cpl + ld e, a + + ld a, d + cpl + ld d, a + + inc l + ret nz + + inc h + ret nz + + inc de + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/negf.asm b/src/arch/zx48k/library-asm/negf.asm index 5d62348a6..b74adb6aa 100644 --- a/src/arch/zx48k/library-asm/negf.asm +++ b/src/arch/zx48k/library-asm/negf.asm @@ -12,14 +12,18 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- -__NEGF: ; A = -A - call __FPSTACK_PUSH - - ; ------------- ROM NEGATE - rst 28h - defb 1Bh ; NEGF - defb 38h; ; END CALC - - jp __FPSTACK_POP + push namespace core + +__NEGF: ; A = -A + call __FPSTACK_PUSH + + ; ------------- ROM NEGATE + rst 28h + defb 1Bh ; NEGF + defb 38h; ; END CALC + + jp __FPSTACK_POP + + pop namespace diff --git a/src/arch/zx48k/library-asm/not32.asm b/src/arch/zx48k/library-asm/not32.asm index 4050cef4b..135a0a921 100644 --- a/src/arch/zx48k/library-asm/not32.asm +++ b/src/arch/zx48k/library-asm/not32.asm @@ -2,13 +2,17 @@ ; 32 bit logical NOT ; ------------------------------------------------------------- -__NOT32: ; A = ¬A - ld a, d - or e - or h - or l - sub 1 ; Gives CARRY only if 0 - sbc a, a; Gives 0 if not carry, FF otherwise - ret + push namespace core + +__NOT32: ; A = ¬A + ld a, d + or e + or h + or l + sub 1 ; Gives CARRY only if 0 + sbc a, a; Gives 0 if not carry, FF otherwise + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/notf.asm b/src/arch/zx48k/library-asm/notf.asm index 9f59c2ad6..6844b005a 100644 --- a/src/arch/zx48k/library-asm/notf.asm +++ b/src/arch/zx48k/library-asm/notf.asm @@ -12,14 +12,18 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- -__NOTF: ; A = ¬A - call __FPSTACK_PUSH - - ; ------------- ROM NOT - rst 28h - defb 30h ; - defb 38h; ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + push namespace core + +__NOTF: ; A = ¬A + call __FPSTACK_PUSH + + ; ------------- ROM NOT + rst 28h + defb 30h ; + defb 38h; ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/ongoto.asm b/src/arch/zx48k/library-asm/ongoto.asm index 9b6759811..bf71c9c8f 100644 --- a/src/arch/zx48k/library-asm/ongoto.asm +++ b/src/arch/zx48k/library-asm/ongoto.asm @@ -2,6 +2,8 @@ ; Implements ON .. GOTO ; ------------------------------------------------------ + push namespace core + __ON_GOSUB: pop hl ex (sp), hl ; hl = beginning of table @@ -29,3 +31,5 @@ __ON_GOTO_START: ld h, (hl) ld l, a jp (hl) + + pop namespace diff --git a/src/arch/zx48k/library-asm/or32.asm b/src/arch/zx48k/library-asm/or32.asm index f462a0b8c..bd4a0e2d0 100644 --- a/src/arch/zx48k/library-asm/or32.asm +++ b/src/arch/zx48k/library-asm/or32.asm @@ -1,6 +1,8 @@ + push namespace core + __OR32: ; Performs logical operation A AND B - ; between DEHL and TOP of the stack. - ; Returns A = 0 (False) or A = FF (True) + ; between DEHL and TOP of the stack. + ; Returns A = 0 (False) or A = FF (True) ld a, h or l @@ -23,3 +25,5 @@ __OR32: ; Performs logical operation A AND B #endif ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/orf.asm b/src/arch/zx48k/library-asm/orf.asm index 402eb94e8..b032a8aed 100644 --- a/src/arch/zx48k/library-asm/orf.asm +++ b/src/arch/zx48k/library-asm/orf.asm @@ -12,14 +12,18 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __ORF: ; A | B - call __FPSTACK_PUSH2 - - ; ------------- ROM NO-OR-NO - rst 28h - defb 07h ; - defb 38h; ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 32 bits + call __FPSTACK_PUSH2 + + ; ------------- ROM NO-OR-NO + rst 28h + defb 07h ; + defb 38h; ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 32 bits + + pop namespace diff --git a/src/arch/zx48k/library-asm/over.asm b/src/arch/zx48k/library-asm/over.asm index 6f2d996ba..ab9d671b1 100644 --- a/src/arch/zx48k/library-asm/over.asm +++ b/src/arch/zx48k/library-asm/over.asm @@ -3,43 +3,47 @@ #include once #include once + push namespace core + OVER: - PROC + PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE + ld (hl), a + + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/paper.asm b/src/arch/zx48k/library-asm/paper.asm index 76d995273..f6ab7dd19 100644 --- a/src/arch/zx48k/library-asm/paper.asm +++ b/src/arch/zx48k/library-asm/paper.asm @@ -3,44 +3,48 @@ #include once + push namespace core + PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/pause.asm b/src/arch/zx48k/library-asm/pause.asm index 544d70f39..b07fb3976 100644 --- a/src/arch/zx48k/library-asm/pause.asm +++ b/src/arch/zx48k/library-asm/pause.asm @@ -1,6 +1,10 @@ ; The PAUSE statement (Calling the ROM) + push namespace core + __PAUSE: - ld b, h + ld b, h ld c, l jp 1F3Dh ; PAUSE_1 + + pop namespace diff --git a/src/arch/zx48k/library-asm/ploadf.asm b/src/arch/zx48k/library-asm/ploadf.asm index e9111f0ed..cba7b7b0a 100644 --- a/src/arch/zx48k/library-asm/ploadf.asm +++ b/src/arch/zx48k/library-asm/ploadf.asm @@ -5,9 +5,13 @@ #include once + push namespace core + __PLOADF: push ix pop hl add hl, de jp __LOADF - + + pop namespace + diff --git a/src/arch/zx48k/library-asm/plot.asm b/src/arch/zx48k/library-asm/plot.asm index fe16b1de1..1c44482f1 100644 --- a/src/arch/zx48k/library-asm/plot.asm +++ b/src/arch/zx48k/library-asm/plot.asm @@ -9,23 +9,25 @@ #include once #include once + push namespace core + PLOT: - PROC + PROC - LOCAL PLOT_SUB - LOCAL PIXEL_ADDR - LOCAL COORDS - LOCAL __PLOT_ERR + LOCAL PLOT_SUB + LOCAL PIXEL_ADDR + LOCAL COORDS + LOCAL __PLOT_ERR LOCAL P_FLAG LOCAL __PLOT_OVER1 P_FLAG EQU 23697 - pop hl - ex (sp), hl ; Callee + pop hl + ex (sp), hl ; Callee - ld b, a - ld c, h + ld b, a + ld c, h #ifdef SCREEN_Y_OFFSET ld a, SCREEN_Y_OFFSET @@ -39,14 +41,14 @@ P_FLAG EQU 23697 ld c, a #endif - ld a, 191 - cp b - jr c, __PLOT_ERR ; jr is faster here (#1) + ld a, 191 + cp b + jr c, __PLOT_ERR ; jr is faster here (#1) __PLOT: ; __FASTCALL__ entry (b, c) = pixel coords (y, x) - ld (COORDS), bc ; Saves current point - ld a, 191 ; Max y coord - call PIXEL_ADDR + ld (COORDS), bc ; Saves current point + ld a, 191 ; Max y coord + call PIXEL_ADDR res 6, h ; Starts from 0 ld bc, (SCREEN_ADDR) add hl, bc ; Now current offset @@ -83,6 +85,8 @@ __PLOT_ERR: jp __OUT_OF_SCREEN_ERR ; Spent 3 bytes, but saves 3 T-States at (#1) PLOT_SUB EQU 22ECh -PIXEL_ADDR EQU 22ACh +PIXEL_ADDR EQU 22ACh COORDS EQU 5C7Dh - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/pow.asm b/src/arch/zx48k/library-asm/pow.asm index 58eb17ea7..549dafb11 100644 --- a/src/arch/zx48k/library-asm/pow.asm +++ b/src/arch/zx48k/library-asm/pow.asm @@ -14,18 +14,22 @@ ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core + __POW: ; Exponentiation - PROC - - call __FPSTACK_PUSH2 - - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - - jp __FPSTACK_POP - - ENDP + PROC + + call __FPSTACK_PUSH2 + + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + + jp __FPSTACK_POP + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/print.asm b/src/arch/zx48k/library-asm/print.asm index 98ef95e5b..7945173d1 100644 --- a/src/arch/zx48k/library-asm/print.asm +++ b/src/arch/zx48k/library-asm/print.asm @@ -18,516 +18,520 @@ #include once #include once -; Putting a comment starting with @INIT
+; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. -#init __PRINT_INIT +#init core.__PRINT_INIT + + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC + PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a + xor a + ld (FLAGS2), a - ret + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A + ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 + LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively #ifndef DISABLE_SCROLL - LOCAL __SCROLL + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret #endif __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later #ifndef DISABLE_SCROLL - call __SCROLL + call __SCROLL #endif - call __LOAD_S_POSN + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) + ld hl, (SCREEN_ADDR) + + ld a, d + ld c, a ; Saves it for later - ld a, d - ld c, a ; Saves it for later - - and 0F8h ; Masks 3 lower bit ; zy - ld d, a + and 0F8h ; Masks 3 lower bit ; zy + ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - - ex af, af' + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR + ex af, af' - cp 90h - jp nc, __PRINT_UDG + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR - ; Print a 8 bit pattern (80h to 8Fh) + cp 90h + jp nc, __PRINT_UDG - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ; Print a 8 bit pattern (80h to 8Fh) + + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 + nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a + ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR + inc de + inc h ; Next line + djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) #ifndef DISABLE_SCROLL - call __SCROLL + call __SCROLL #endif - call __LOAD_S_POSN + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d #ifndef DISABLE_SCROLL - ld hl, __TVFLAGS - set 1, (hl) - dec a + ld hl, __TVFLAGS + set 1, (hl) + dec a #else - xor a + xor a #endif __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE - + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE + __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret - + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret + __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack + ; COL in A register + ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen + call __IN_SCREEN + ret nc ; Return if out of screen #ifndef DISABLE_SCROLL - ld hl, __TVFLAGS - res 1, (hl) + ld hl, __TVFLAGS + res 1, (hl) #endif - jp __SAVE_S_POSN - - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 - + jp __SAVE_S_POSN + + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + __PRINT_TABLE: ; Jump table for 0 .. 22 codes - - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - - ENDP - + + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + + ENDP + + pop namespace + diff --git a/src/arch/zx48k/library-asm/print_eol_attr.asm b/src/arch/zx48k/library-asm/print_eol_attr.asm index 0687c3718..6d4e25a2e 100644 --- a/src/arch/zx48k/library-asm/print_eol_attr.asm +++ b/src/arch/zx48k/library-asm/print_eol_attr.asm @@ -4,6 +4,10 @@ #include once #include once + push namespace core + PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + + pop namespace diff --git a/src/arch/zx48k/library-asm/printf.asm b/src/arch/zx48k/library-asm/printf.asm index e76cc5a1f..917130b62 100644 --- a/src/arch/zx48k/library-asm/printf.asm +++ b/src/arch/zx48k/library-asm/printf.asm @@ -2,42 +2,46 @@ #include once #include once + push namespace core + __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC + PROC - LOCAL RECLAIM2 - LOCAL STK_END + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END + ld hl, (STK_END) + push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL + ex de, hl ; String position now in HL - push bc + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc + call __PRINT_STR + pop bc + inc bc - jp RECLAIM2 ; Frees TMP Memory + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/printf16.asm b/src/arch/zx48k/library-asm/printf16.asm index 55c4f67b6..e5b4e8f2c 100644 --- a/src/arch/zx48k/library-asm/printf16.asm +++ b/src/arch/zx48k/library-asm/printf16.asm @@ -2,56 +2,60 @@ #include once #include once + push namespace core + __PRINTF16: ; Prints a 32bit 16.16 fixed point number - PROC + PROC - LOCAL __PRINT_FIX_LOOP - LOCAL __PRINTF16_2 + LOCAL __PRINT_FIX_LOOP + LOCAL __PRINTF16_2 - bit 7, d - jr z, __PRINTF16_2 - call __NEG32 - call __PRINT_MINUS + bit 7, d + jr z, __PRINTF16_2 + call __NEG32 + call __PRINT_MINUS __PRINTF16_2: - push hl - ex de, hl - call __PRINTU16 ; Prints integer part - pop hl + push hl + ex de, hl + call __PRINTU16 ; Prints integer part + pop hl - ld a, h - or l - ret z ; Returns if integer + ld a, h + or l + ret z ; Returns if integer - push hl - ld a, '.' - call __PRINT_DIGIT ; Prints decimal point - pop hl + push hl + ld a, '.' + call __PRINT_DIGIT ; Prints decimal point + pop hl __PRINT_FIX_LOOP: - ld a, h - or l - ret z ; Returns if no more decimals - - xor a - ld d, h - ld e, l - ; Fast NUM * 10 multiplication - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 2) - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 4) - - add hl, de ; - adc a, 0 ; AHL = AHL + DE (= X * 5) - add hl, hl - adc a, a ; AHL = AHL * 2 (= X * 10) - - push hl - or '0' - call __PRINT_DIGIT - pop hl - jp __PRINT_FIX_LOOP - - ENDP + ld a, h + or l + ret z ; Returns if no more decimals + + xor a + ld d, h + ld e, l + ; Fast NUM * 10 multiplication + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 2) + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 4) + + add hl, de ; + adc a, 0 ; AHL = AHL + DE (= X * 5) + add hl, hl + adc a, a ; AHL = AHL * 2 (= X * 10) + + push hl + or '0' + call __PRINT_DIGIT + pop hl + jp __PRINT_FIX_LOOP + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/printi16.asm b/src/arch/zx48k/library-asm/printi16.asm index 1c78224f3..6eadfb7e7 100644 --- a/src/arch/zx48k/library-asm/printi16.asm +++ b/src/arch/zx48k/library-asm/printi16.asm @@ -3,37 +3,41 @@ #include once #include once + push namespace core + __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC + ; Converts 16 to 32 bits + PROC - LOCAL __PRINTU_LOOP - ld a, h - or a + LOCAL __PRINTU_LOOP + ld a, h + or a - jp p, __PRINTU16 + jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - - ENDP + ld a, h + or l + jp z, __PRINTU_START + + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/printi32.asm b/src/arch/zx48k/library-asm/printi32.asm index 845041fe4..e619fa492 100644 --- a/src/arch/zx48k/library-asm/printi32.asm +++ b/src/arch/zx48k/library-asm/printi32.asm @@ -4,44 +4,48 @@ #include once + push namespace core + __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 + ld a, d + or a + jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP + PROC + LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - - push bc - - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + + push bc + + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/printi8.asm b/src/arch/zx48k/library-asm/printi8.asm index 899c35988..dcfaaeb9e 100644 --- a/src/arch/zx48k/library-asm/printi8.asm +++ b/src/arch/zx48k/library-asm/printi8.asm @@ -1,38 +1,42 @@ #include once #include once + push namespace core + __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC + PROC - LOCAL __PRINTU_LOOP + LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - - ENDP + or a + jp z, __PRINTU_START + + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/printnum.asm b/src/arch/zx48k/library-asm/printnum.asm index 6758e0916..8e0c21f63 100644 --- a/src/arch/zx48k/library-asm/printnum.asm +++ b/src/arch/zx48k/library-asm/printnum.asm @@ -1,34 +1,38 @@ #include once #include once + push namespace core + __PRINTU_START: - PROC + PROC + + LOCAL __PRINTU_CONT - LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT - ld a, '0' - jp __PRINT_DIGIT - __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + + ENDP - ENDP - __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs - + pop namespace + + diff --git a/src/arch/zx48k/library-asm/printstr.asm b/src/arch/zx48k/library-asm/printstr.asm index 3bd609ed3..d680e8646 100644 --- a/src/arch/zx48k/library-asm/printstr.asm +++ b/src/arch/zx48k/library-asm/printstr.asm @@ -6,51 +6,55 @@ ; PRINT command routine ; Prints string pointed by HL + push namespace core + PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later + ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL + ld a, h + or l + ret z ; Return if the pointer is NULL - push hl + push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/pstore32.asm b/src/arch/zx48k/library-asm/pstore32.asm index 1cda7cf9a..aac91082b 100644 --- a/src/arch/zx48k/library-asm/pstore32.asm +++ b/src/arch/zx48k/library-asm/pstore32.asm @@ -1,10 +1,14 @@ #include once ; Stores a 32 bit integer number (DE,HL) at (IX + BC) + push namespace core + __PSTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc - jp __STORE32 + push hl + push ix + pop hl + add hl, bc + pop bc + jp __STORE32 + + pop namespace diff --git a/src/arch/zx48k/library-asm/pstoref.asm b/src/arch/zx48k/library-asm/pstoref.asm index 6d04dd21c..c387b5547 100644 --- a/src/arch/zx48k/library-asm/pstoref.asm +++ b/src/arch/zx48k/library-asm/pstoref.asm @@ -1,17 +1,21 @@ -; Stores FP number in A ED CB at location HL+IX -; HL = Offset -; IX = Stack Frame -; A ED CB = FP Number - -#include once - -; Stored a float number in A ED CB into the address pointed by IX + HL -__PSTOREF: - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + DE - pop de - jp __STOREF - +; Stores FP number in A ED CB at location HL+IX +; HL = Offset +; IX = Stack Frame +; A ED CB = FP Number + +#include once + +; Stored a float number in A ED CB into the address pointed by IX + HL + push namespace core + +__PSTOREF: + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + DE + pop de + jp __STOREF + + pop namespace + diff --git a/src/arch/zx48k/library-asm/pstorestr.asm b/src/arch/zx48k/library-asm/pstorestr.asm index ccec74fb0..e65d1e340 100644 --- a/src/arch/zx48k/library-asm/pstorestr.asm +++ b/src/arch/zx48k/library-asm/pstorestr.asm @@ -1,14 +1,18 @@ ; vim:ts=4:et:sw=4 -; +; ; Stores an string (pointer to the HEAP by DE) into the address pointed ; by (IX + BC). A new copy of the string is created into the HEAP ; #include once + push namespace core + __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace + diff --git a/src/arch/zx48k/library-asm/pstorestr2.asm b/src/arch/zx48k/library-asm/pstorestr2.asm index ce3eadd7d..85109c3b3 100644 --- a/src/arch/zx48k/library-asm/pstorestr2.asm +++ b/src/arch/zx48k/library-asm/pstorestr2.asm @@ -1,5 +1,5 @@ ; vim:ts=4:et:sw=4 -; +; ; Stores an string (pointer to the HEAP by DE) into the address pointed ; by (IX + BC). No new copy of the string is created into the HEAP, since ; it's supposed it's already created (temporary string) @@ -7,9 +7,13 @@ #include once + push namespace core + __PSTORE_STR2: push ix pop hl add hl, bc jp __STORE_STR2 + pop namespace + diff --git a/src/arch/zx48k/library-asm/pushf.asm b/src/arch/zx48k/library-asm/pushf.asm index 19ca89633..d8a76c5ec 100644 --- a/src/arch/zx48k/library-asm/pushf.asm +++ b/src/arch/zx48k/library-asm/pushf.asm @@ -1,9 +1,11 @@ -; Routine to push Float pointed by HL +; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core + __FP_PUSH_REV: push hl exx @@ -25,4 +27,6 @@ __FP_PUSH_REV: exx ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/random.asm b/src/arch/zx48k/library-asm/random.asm index 27094e761..ef58fec0d 100644 --- a/src/arch/zx48k/library-asm/random.asm +++ b/src/arch/zx48k/library-asm/random.asm @@ -1,5 +1,7 @@ ; RANDOM functions + push namespace core + RANDOMIZE: ; Randomize with 32 bit seed in DE HL ; if SEED = 0, calls ROM to take frames as seed @@ -7,7 +9,7 @@ RANDOMIZE: LOCAL TAKE_FRAMES LOCAL FRAMES - + ld a, h or l or d @@ -36,7 +38,7 @@ RANDOM_SEED_LOW EQU 23670 ; RANDOM seed, 16 lower bits RAND: PROC LOCAL RAND_LOOP - ld b, 4 + ld b, 4 RAND_LOOP: ld hl,(RANDOM_SEED_LOW) ; xz -> yw ld de,0C0DEh ; yw -> zt @@ -104,13 +106,15 @@ RND_LOOP: ; Now undo last mantissa left-shift once ccf ; Clears carry to insert a 0 bit back into mantissa -> positive FP number rra - rr d + rr d rr c rr b - + ld e, a ; E must have the highest byte ld a, l ; exponent in A ret ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/read_restore.asm b/src/arch/zx48k/library-asm/read_restore.asm index a6f7bf3b9..3674f5134 100644 --- a/src/arch/zx48k/library-asm/read_restore.asm +++ b/src/arch/zx48k/library-asm/read_restore.asm @@ -39,6 +39,8 @@ ;; Updates restore point to the given HL mem. address + push namespace core + __RESTORE: PROC LOCAL __DATA_ADDR @@ -299,14 +301,14 @@ __01_decode_string: ld (__DATA_ADDR), hl ;; Store address of next DATA ex de, hl jp __LOADSTR - + __02_decode_byte: __03_decode_ubyte: ld a, (hl) inc hl ld (__DATA_ADDR), hl ret - + __04_decode_integer: __05_decode_uinteger: ld e, (hl) @@ -316,7 +318,7 @@ __05_decode_uinteger: ld (__DATA_ADDR), hl ex de, hl ret - + __06_decode_long: __07_decode_ulong: __08_decode_fixed: @@ -349,3 +351,5 @@ __DATA_ADDR: ;; Stores current DATA ptr #undef _u32 #undef _f16 #undef _flt + + pop namespace diff --git a/src/arch/zx48k/library-asm/realloc.asm b/src/arch/zx48k/library-asm/realloc.asm index 67473d4b1..e5c803d34 100644 --- a/src/arch/zx48k/library-asm/realloc.asm +++ b/src/arch/zx48k/library-asm/realloc.asm @@ -1,6 +1,6 @@ ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa -; (a.k.a. Boriel) +; (a.k.a. Boriel) ; http://www.boriel.com ; ; This ASM library is licensed under the BSD license @@ -13,20 +13,20 @@ ; The heap is implemented as a linked list of free blocks. ; Each free block contains this info: -; -; +----------------+ <-- HEAP START +; +; +----------------+ <-- HEAP START ; | Size (2 bytes) | ; | 0 | <-- Size = 0 => DUMMY HEADER BLOCK ; +----------------+ ; | Next (2 bytes) |---+ -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | <-- If Size > 4, then this contains (size - 4) bytes ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ @@ -35,14 +35,14 @@ ; | (0 if Size = 4)| | ; +----------------+ | ; | <-- This zone is in use (Already allocated) -; +----------------+ <-+ +; +----------------+ <-+ ; | Size (2 bytes) | ; +----------------+ ; | Next (2 bytes) |---+ ; +----------------+ | ; | | | ; | (0 if Size = 4)| | -; +----------------+ <-+ +; +----------------+ <-+ ; | Next (2 bytes) |--> NULL => END OF LIST ; | 0 = NULL | ; +----------------+ @@ -59,7 +59,7 @@ ; MEMORY MANAGER ; -; This library must be initialized calling __MEM_INIT with +; This library must be initialized calling __MEM_INIT with ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. @@ -89,69 +89,73 @@ ; the new size is adjusted. If BC < original length, the content ; will be truncated. Otherwise, extra block content might contain ; memory garbage. -; +; ; --------------------------------------------------------------------- + push namespace core + __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - - LOCAL __REALLOC_END - - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - - dec hl ; HL = Block start - - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + + LOCAL __REALLOC_END + + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + + dec hl ; HL = Block start + + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret + dec hl ; Set HL + dec hl ; To begin of block + ret + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/save.asm b/src/arch/zx48k/library-asm/save.asm index 618ecb0ad..98c6f4ce3 100644 --- a/src/arch/zx48k/library-asm/save.asm +++ b/src/arch/zx48k/library-asm/save.asm @@ -6,10 +6,12 @@ #include once #include once + push namespace core + SAVE_CODE: PROC - + LOCAL MEMBOT LOCAL SAVE_CONT LOCAL ROM_SAVE @@ -40,28 +42,28 @@ __SAVE_CODE: ; INLINE version ld a, b or c jr z, SAVE_EMPTY_ERROR ; Return if block length == 0 - + push ix ld a, h or l jr z, __ERR_EMPTY ; Return if NULL STRING - + ld ix, MEMBOT ld (ix + 00), 3 ; CODE - + ld (ix + 11), c ld (ix + 12), b ; Store long in bytes ld (ix + 13), e ld (ix + 14), d ; Store address in bytes - + push hl ld bc, 9 ld HL, MEMBOT + 1 ld DE, MEMBOT + 2 ld (hl), ' ' ldir ; Fill the filename with blanks - pop hl - + pop hl + ld c, (hl) inc hl ld b, (hl) @@ -72,7 +74,7 @@ __SAVE_CODE: ; INLINE version __ERR_EMPTY: ld a, ERROR_InvalidFileName jr z, SAVE_STOP ; Return if str len == 0 - + ex de, hl ; Saves HL in DE ld hl, 10 or a @@ -80,14 +82,14 @@ __ERR_EMPTY: ex de, hl jr nc, SAVE_CONT ; Ok BC <= 10 ld bc, 10 ; BC at most 10 chars - + SAVE_CONT: ld de, MEMBOT + 1 ldir ; Copy String block NAME ld hl, (STR_PTR) call MEM_FREE ld l, (ix + 13) - ld h, (ix + 14) ; Restores start of bytes + ld h, (ix + 14) ; Restores start of bytes ld a, r push af @@ -178,5 +180,7 @@ SA_CHK_BRK: ret #endif - + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/sgn.asm b/src/arch/zx48k/library-asm/sgn.asm index d564bb006..47eb9e452 100644 --- a/src/arch/zx48k/library-asm/sgn.asm +++ b/src/arch/zx48k/library-asm/sgn.asm @@ -1,5 +1,7 @@ ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core + PROC LOCAL __ENDSGN @@ -14,27 +16,29 @@ __SGNF: __SGNF16: __SGNI32: - ld a, h - or l - or e - or d - ret z + ld a, h + or l + or e + or d + ret z ld a, d jr __ENDSGN __SGNI16: - ld a, h - or l - ret z - ld a, h + ld a, h + or l + ret z + ld a, h __ENDSGN: - or a - ld a, 1 - ret p - neg - ret + or a + ld a, 1 + ret p + neg + ret ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/sgni8.asm b/src/arch/zx48k/library-asm/sgni8.asm index 65690db00..bbfddd63c 100644 --- a/src/arch/zx48k/library-asm/sgni8.asm +++ b/src/arch/zx48k/library-asm/sgni8.asm @@ -1,10 +1,14 @@ ; Returns SGN (SIGN) for 8 bits signed integer + push namespace core + __SGNI8: - or a - ret z - ld a, 1 - ret p - neg - ret + or a + ret z + ld a, 1 + ret p + neg + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/sgnu16.asm b/src/arch/zx48k/library-asm/sgnu16.asm index 129c6afa1..6f649236f 100644 --- a/src/arch/zx48k/library-asm/sgnu16.asm +++ b/src/arch/zx48k/library-asm/sgnu16.asm @@ -1,9 +1,13 @@ ; Returns SGN (SIGN) for 16 bits unsigned integer + push namespace core + __SGNU16: - ld a, h - or l - ret z - ld a, 1 - ret + ld a, h + or l + ret z + ld a, 1 + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/sgnu32.asm b/src/arch/zx48k/library-asm/sgnu32.asm index 4926cb8be..8130a3b71 100644 --- a/src/arch/zx48k/library-asm/sgnu32.asm +++ b/src/arch/zx48k/library-asm/sgnu32.asm @@ -1,12 +1,16 @@ ; Returns SGN (SIGN) for 32 bits unsigned integer + push namespace core + __SGNU32: - ld a, h - or l - or d - or e - ret z - - ld a, 1 - ret + ld a, h + or l + or d + or e + ret z + + ld a, 1 + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/sgnu8.asm b/src/arch/zx48k/library-asm/sgnu8.asm index 1b7f4728c..89de890f8 100644 --- a/src/arch/zx48k/library-asm/sgnu8.asm +++ b/src/arch/zx48k/library-asm/sgnu8.asm @@ -1,8 +1,12 @@ ; Returns SGN (SIGN) for 8 bits unsigned integera + push namespace core + __SGNU8: - or a + or a ret z - ld a, 1 - ret + ld a, 1 + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/shl32.asm b/src/arch/zx48k/library-asm/shl32.asm index 722207ac8..eb7a76dc6 100644 --- a/src/arch/zx48k/library-asm/shl32.asm +++ b/src/arch/zx48k/library-asm/shl32.asm @@ -1,9 +1,13 @@ + push namespace core + __SHL32: ; Left Logical Shift 32 bits - sla l - rl h - rl e - rl d - ret + sla l + rl h + rl e + rl d + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/shra32.asm b/src/arch/zx48k/library-asm/shra32.asm index 94d815a4b..978cd28f0 100644 --- a/src/arch/zx48k/library-asm/shra32.asm +++ b/src/arch/zx48k/library-asm/shra32.asm @@ -1,9 +1,13 @@ + push namespace core + __SHRA32: ; Right Arithmetical Shift 32 bits sra d - rr e + rr e rr h rr l - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/shrl32.asm b/src/arch/zx48k/library-asm/shrl32.asm index 6aada4595..51edeb924 100644 --- a/src/arch/zx48k/library-asm/shrl32.asm +++ b/src/arch/zx48k/library-asm/shrl32.asm @@ -1,9 +1,13 @@ + push namespace core + __SHRL32: ; Right Logical Shift 32 bits srl d - rr e + rr e rr h rr l - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/sin.asm b/src/arch/zx48k/library-asm/sin.asm index b9954da3a..bf76718da 100644 --- a/src/arch/zx48k/library-asm/sin.asm +++ b/src/arch/zx48k/library-asm/sin.asm @@ -1,11 +1,15 @@ #include once + push namespace core + SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/sposn.asm b/src/arch/zx48k/library-asm/sposn.asm index c406a1c99..4c8a62d2c 100644 --- a/src/arch/zx48k/library-asm/sposn.asm +++ b/src/arch/zx48k/library-asm/sposn.asm @@ -1,31 +1,35 @@ ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret - + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret + __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 -S_POSN EQU 23688 +S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/sqrt.asm b/src/arch/zx48k/library-asm/sqrt.asm index ac6d8adbc..eac9a50c9 100644 --- a/src/arch/zx48k/library-asm/sqrt.asm +++ b/src/arch/zx48k/library-asm/sqrt.asm @@ -1,11 +1,15 @@ #include once + push namespace core + SQRT: ; Computes SQRT(x) using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 28h ; SQRT + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 28h ; SQRT - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/stackf.asm b/src/arch/zx48k/library-asm/stackf.asm index 2e058acbf..5546bdd5a 100644 --- a/src/arch/zx48k/library-asm/stackf.asm +++ b/src/arch/zx48k/library-asm/stackf.asm @@ -3,13 +3,15 @@ ; ------------------------------------------------------------- + push namespace core + __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx @@ -25,21 +27,23 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx push hl ; Caller-Caller return addr exx - + jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + + pop namespace diff --git a/src/arch/zx48k/library-asm/store32.asm b/src/arch/zx48k/library-asm/store32.asm index ef76456ed..753b20e28 100644 --- a/src/arch/zx48k/library-asm/store32.asm +++ b/src/arch/zx48k/library-asm/store32.asm @@ -1,23 +1,27 @@ + push namespace core + __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret - + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + + pop namespace + diff --git a/src/arch/zx48k/library-asm/storef.asm b/src/arch/zx48k/library-asm/storef.asm index 78d6dd105..bda382fcf 100644 --- a/src/arch/zx48k/library-asm/storef.asm +++ b/src/arch/zx48k/library-asm/storef.asm @@ -1,28 +1,32 @@ + push namespace core + __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret - + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + + pop namespace + diff --git a/src/arch/zx48k/library-asm/storestr.asm b/src/arch/zx48k/library-asm/storestr.asm index fbe427d1a..c5934698b 100644 --- a/src/arch/zx48k/library-asm/storestr.asm +++ b/src/arch/zx48k/library-asm/storestr.asm @@ -12,6 +12,8 @@ #include once + push namespace core + __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -43,3 +45,5 @@ __STORE_STR: pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/storestr2.asm b/src/arch/zx48k/library-asm/storestr2.asm index 0a2ff1c4a..b652f3194 100644 --- a/src/arch/zx48k/library-asm/storestr2.asm +++ b/src/arch/zx48k/library-asm/storestr2.asm @@ -7,33 +7,37 @@ #include once + push namespace core + __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - - push de - call __MEM_FREE - pop de - - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + + push de + call __MEM_FREE + pop de + + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/str.asm b/src/arch/zx48k/library-asm/str.asm index dda35e3d4..49f63d2a9 100644 --- a/src/arch/zx48k/library-asm/str.asm +++ b/src/arch/zx48k/library-asm/str.asm @@ -8,70 +8,74 @@ #include once #include once + push namespace core + __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - - push bc - push de - - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - - pop de - pop bc - - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - - ex de, hl ; HL = start of original string - ldir ; Copies string content - - pop de ; Original (ROM-CALC) string - pop bc ; Original Length - + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + + push bc + push de + + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + + pop de + pop bc + + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + + ex de, hl ; HL = start of original string + ldir ; Copies string content + + pop de ; Original (ROM-CALC) string + pop bc ; Original Length + __STR_END: - ex de, hl - inc bc + ex de, hl + inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result - ret + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/strarraycpy.asm b/src/arch/zx48k/library-asm/strarraycpy.asm index c4c4b36db..6ed8d80f0 100644 --- a/src/arch/zx48k/library-asm/strarraycpy.asm +++ b/src/arch/zx48k/library-asm/strarraycpy.asm @@ -10,6 +10,8 @@ #include once #include once + push namespace core + STR_ARRAYCOPY: ; Copies an array of string a$ = b$ ; Parameters in the stack: @@ -63,4 +65,6 @@ LOOP: ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/strcat.asm b/src/arch/zx48k/library-asm/strcat.asm index d4971d2b4..8a3a4c7de 100644 --- a/src/arch/zx48k/library-asm/strcat.asm +++ b/src/arch/zx48k/library-asm/strcat.asm @@ -1,126 +1,130 @@ #include once #include once + push namespace core + __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ - PROC + PROC - LOCAL __STR_CONT - LOCAL __STRCATEND + LOCAL __STR_CONT + LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length + inc bc + inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx + exx + pop de ; D'E' = b$ + exx - pop bc ; LEN(a$) + pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ + push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx - pop de ; DE = b$ + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - - push hl ; Saves HL to return it later - - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + + push hl ; Saves HL to return it later + + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/strcpy.asm b/src/arch/zx48k/library-asm/strcpy.asm index 305aadadf..091e2e11c 100644 --- a/src/arch/zx48k/library-asm/strcpy.asm +++ b/src/arch/zx48k/library-asm/strcpy.asm @@ -3,94 +3,98 @@ ; String library + push namespace core + __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - - push de - push hl - - ld a, h - or l - jr z, __STRREALLOC - - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + + push de + push hl + + ld a, h + or l + jr z, __STRREALLOC + + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ + pop de ; DE = &a$ + pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/strictbool.asm b/src/arch/zx48k/library-asm/strictbool.asm index 1d0e94264..0461b1a55 100644 --- a/src/arch/zx48k/library-asm/strictbool.asm +++ b/src/arch/zx48k/library-asm/strictbool.asm @@ -1,9 +1,13 @@ ; This routine is called if --strict-boolean was set at the command line. ; It will make any boolean result to be always 0 or 1 + push namespace core + __NORMALIZE_BOOLEAN: or a ret z ld a, 1 ret + pop namespace + diff --git a/src/arch/zx48k/library-asm/string.asm b/src/arch/zx48k/library-asm/string.asm index 85c270a97..d9e94d03c 100644 --- a/src/arch/zx48k/library-asm/string.asm +++ b/src/arch/zx48k/library-asm/string.asm @@ -2,225 +2,229 @@ #include once + push namespace core + __STR_ISNULL: ; Returns A = FF if HL is 0, 0 otherwise - ld a, h - or l - sub 1 ; Only CARRY if HL is NULL - sbc a, a ; Only FF if HL is NULL (0 otherwise) - ret + ld a, h + or l + sub 1 ; Only CARRY if HL is NULL + sbc a, a ; Only FF if HL is NULL (0 otherwise) + ret __STRCMP: ; Compares strings at HL, DE: Returns 0 if EQual, -1 if HL < DE, +1 if HL > DE - ; A register is preserved and returned in A' - PROC ; __FASTCALL__ - - LOCAL __STRCMPZERO - LOCAL __STRCMPEXIT - LOCAL __STRCMPLOOP - LOCAL __NOPRESERVEBC - LOCAL __EQULEN - LOCAL __EQULEN1 - LOCAL __HLZERO - - ex af, af' ; Saves current A register in A' (it's used by STRXX comparison functions) - - ld a, h - or l - jr z, __HLZERO - - ld a, d - or e - ld a, 1 - ret z ; Returns +1 if HL is not NULL and DE is NULL - - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$) - push hl ; HL = &a$, saves it - - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ex de, hl ; HL = LEN(b$), de = &b$ - - ; At this point Carry is cleared, and A reg. = 1 - sbc hl, bc ; Carry if len(b$) > len(a$) - jr z, __EQULEN ; Jump if they have the same length so A reg. = 0 - jr c, __EQULEN1 ; Jump if len(b$) > len(a$) so A reg. = 1 + ; A register is preserved and returned in A' + PROC ; __FASTCALL__ + + LOCAL __STRCMPZERO + LOCAL __STRCMPEXIT + LOCAL __STRCMPLOOP + LOCAL __NOPRESERVEBC + LOCAL __EQULEN + LOCAL __EQULEN1 + LOCAL __HLZERO + + ex af, af' ; Saves current A register in A' (it's used by STRXX comparison functions) + + ld a, h + or l + jr z, __HLZERO + + ld a, d + or e + ld a, 1 + ret z ; Returns +1 if HL is not NULL and DE is NULL + + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$) + push hl ; HL = &a$, saves it + + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ex de, hl ; HL = LEN(b$), de = &b$ + + ; At this point Carry is cleared, and A reg. = 1 + sbc hl, bc ; Carry if len(b$) > len(a$) + jr z, __EQULEN ; Jump if they have the same length so A reg. = 0 + jr c, __EQULEN1 ; Jump if len(b$) > len(a$) so A reg. = 1 __NOPRESERVEBC: - add hl, bc ; Restore HL (original length) - ld b, h ; len(b$) <= len(a$) - ld c, l ; so BC = hl - dec a ; At this point A register = 0, it must be -1 since len(a$) > len(b$) + add hl, bc ; Restore HL (original length) + ld b, h ; len(b$) <= len(a$) + ld c, l ; so BC = hl + dec a ; At this point A register = 0, it must be -1 since len(a$) > len(b$) __EQULEN: - dec a ; A = 0 if len(a$) = len(b$), -1 otherwise + dec a ; A = 0 if len(a$) = len(b$), -1 otherwise __EQULEN1: - pop hl ; Recovers A$ pointer - push af ; Saves A for later (Value to return if strings reach the end) - ld a, b - or c - jr z, __STRCMPZERO ; empty string being compared + pop hl ; Recovers A$ pointer + push af ; Saves A for later (Value to return if strings reach the end) + ld a, b + or c + jr z, __STRCMPZERO ; empty string being compared - ; At this point: BC = lesser length, DE and HL points to b$ and a$ chars respectively + ; At this point: BC = lesser length, DE and HL points to b$ and a$ chars respectively __STRCMPLOOP: - ld a, (de) - cpi - jr nz, __STRCMPEXIT ; (HL) != (DE). Examine carry - jp po, __STRCMPZERO ; END of string (both are equal) - inc de - jp __STRCMPLOOP + ld a, (de) + cpi + jr nz, __STRCMPEXIT ; (HL) != (DE). Examine carry + jp po, __STRCMPZERO ; END of string (both are equal) + inc de + jp __STRCMPLOOP __STRCMPZERO: - pop af ; This is -1 if len(a$) < len(b$), +1 if len(b$) > len(a$), 0 otherwise - ret + pop af ; This is -1 if len(a$) < len(b$), +1 if len(b$) > len(a$), 0 otherwise + ret __STRCMPEXIT: ; Sets A with the following value - dec hl ; Get back to the last char - cp (hl) - sbc a, a ; A = -1 if carry => (DE) < (HL); 0 otherwise (DE) > (HL) - cpl ; A = -1 if (HL) < (DE), 0 otherwise - add a, a ; A = A * 2 (thus -2 or 0) - inc a ; A = A + 1 (thus -1 or 1) + dec hl ; Get back to the last char + cp (hl) + sbc a, a ; A = -1 if carry => (DE) < (HL); 0 otherwise (DE) > (HL) + cpl ; A = -1 if (HL) < (DE), 0 otherwise + add a, a ; A = A * 2 (thus -2 or 0) + inc a ; A = A + 1 (thus -1 or 1) - pop bc ; Discard top of the stack - ret + pop bc ; Discard top of the stack + ret __HLZERO: - or d - or e - ret z ; Returns 0 (EQ) if HL == DE == NULL - ld a, -1 - ret ; Returns -1 if HL is NULL and DE is not NULL + or d + or e + ret z ; Returns 0 (EQ) if HL == DE == NULL + ld a, -1 + ret ; Returns -1 if HL is NULL and DE is not NULL - ENDP + ENDP - ; The following routines perform string comparison operations (<, >, ==, etc...) - ; On return, A will contain 0 for False, other value for True - ; Register A' will determine whether the incoming strings (HL, DE) will be freed - ; from dynamic memory on exit: - ; Bit 0 => 1 means HL will be freed. - ; Bit 1 => 1 means DE will be freed. + ; The following routines perform string comparison operations (<, >, ==, etc...) + ; On return, A will contain 0 for False, other value for True + ; Register A' will determine whether the incoming strings (HL, DE) will be freed + ; from dynamic memory on exit: + ; Bit 0 => 1 means HL will be freed. + ; Bit 1 => 1 means DE will be freed. __STREQ: ; Compares a$ == b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False) - push hl - push de - call __STRCMP - pop de - pop hl - - ;inc a ; If A == -1, return 0 - ;jp z, __FREE_STR - - ;dec a ; - ;dec a ; Return -1 if a = 0 (True), returns 0 if A == 1 (False) - sub 1 - sbc a, a - jp __FREE_STR + push hl + push de + call __STRCMP + pop de + pop hl + + ;inc a ; If A == -1, return 0 + ;jp z, __FREE_STR + + ;dec a ; + ;dec a ; Return -1 if a = 0 (True), returns 0 if A == 1 (False) + sub 1 + sbc a, a + jp __FREE_STR __STRNE: ; Compares a$ != b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False) - push hl - push de - call __STRCMP - pop de - pop hl + push hl + push de + call __STRCMP + pop de + pop hl - ;jp z, __FREE_STR + ;jp z, __FREE_STR - ;ld a, 0FFh ; Returns 0xFFh (True) - jp __FREE_STR + ;ld a, 0FFh ; Returns 0xFFh (True) + jp __FREE_STR __STRLT: ; Compares a$ < b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False) - push hl - push de - call __STRCMP - pop de - pop hl + push hl + push de + call __STRCMP + pop de + pop hl - jp z, __FREE_STR ; Returns 0 if A == B + jp z, __FREE_STR ; Returns 0 if A == B - dec a ; Returns 0 if A == 1 => a$ > b$ - ;jp z, __FREE_STR + dec a ; Returns 0 if A == 1 => a$ > b$ + ;jp z, __FREE_STR - ;inc a ; A = FE now (-2). Set it to FF and return - jp __FREE_STR + ;inc a ; A = FE now (-2). Set it to FF and return + jp __FREE_STR __STRLE: ; Compares a$ <= b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False) - push hl - push de - call __STRCMP - pop de - pop hl + push hl + push de + call __STRCMP + pop de + pop hl - dec a ; Returns 0 if A == 1 => a$ < b$ - ;jp z, __FREE_STR + dec a ; Returns 0 if A == 1 => a$ < b$ + ;jp z, __FREE_STR - ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return - jp __FREE_STR + ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return + jp __FREE_STR __STRGT: ; Compares a$ > b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False) - push hl - push de - call __STRCMP - pop de - pop hl + push hl + push de + call __STRCMP + pop de + pop hl - jp z, __FREE_STR ; Returns 0 if A == B + jp z, __FREE_STR ; Returns 0 if A == B - inc a ; Returns 0 if A == -1 => a$ < b$ - ;jp z, __FREE_STR ; Returns 0 if A == B + inc a ; Returns 0 if A == -1 => a$ < b$ + ;jp z, __FREE_STR ; Returns 0 if A == B - ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return - jp __FREE_STR + ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return + jp __FREE_STR __STRGE: ; Compares a$ >= b$ (HL = ptr a$, DE = ptr b$). Returns FF (True) or 0 (False) - push hl - push de - call __STRCMP - pop de - pop hl + push hl + push de + call __STRCMP + pop de + pop hl - inc a ; Returns 0 if A == -1 => a$ < b$ - ;jr z, __FREE_STR + inc a ; Returns 0 if A == -1 => a$ < b$ + ;jr z, __FREE_STR - ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return + ;ld a, 0FFh ; A = FE now (-2). Set it to FF and return __FREE_STR: ; This exit point will test A' for bits 0 and 1 - ; If bit 0 is 1 => Free memory from HL pointer - ; If bit 1 is 1 => Free memory from DE pointer - ; Finally recovers A, to return the result - PROC + ; If bit 0 is 1 => Free memory from HL pointer + ; If bit 1 is 1 => Free memory from DE pointer + ; Finally recovers A, to return the result + PROC - LOCAL __FREE_STR2 - LOCAL __FREE_END + LOCAL __FREE_STR2 + LOCAL __FREE_END - ex af, af' - bit 0, a - jr z, __FREE_STR2 + ex af, af' + bit 0, a + jr z, __FREE_STR2 - push af - push de - call __MEM_FREE - pop de - pop af + push af + push de + call __MEM_FREE + pop de + pop af __FREE_STR2: - bit 1, a - jr z, __FREE_END + bit 1, a + jr z, __FREE_END - ex de, hl - call __MEM_FREE + ex de, hl + call __MEM_FREE __FREE_END: - ex af, af' - ret - - ENDP + ex af, af' + ret + + ENDP + + pop namespace diff --git a/src/arch/zx48k/library-asm/strlen.asm b/src/arch/zx48k/library-asm/strlen.asm index cfd39622c..cb4a880af 100644 --- a/src/arch/zx48k/library-asm/strlen.asm +++ b/src/arch/zx48k/library-asm/strlen.asm @@ -2,15 +2,19 @@ ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core + __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z + ld a, h + or l + ret z + + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + pop namespace diff --git a/src/arch/zx48k/library-asm/strslice.asm b/src/arch/zx48k/library-asm/strslice.asm index ece969e35..ec1b12b95 100644 --- a/src/arch/zx48k/library-asm/strslice.asm +++ b/src/arch/zx48k/library-asm/strslice.asm @@ -5,12 +5,12 @@ ; A register => 0 => the HL pointer wont' be freed from the HEAP ; e.g. a$(5 TO 10) => HL = a$; DE = 5; BC = 10 -; This implements a$(X to Y) being X and Y first and +; This implements a$(X to Y) being X and Y first and ; last characters respectively. If X > Y, NULL is returned ; Otherwise returns a pointer to a$ FROM X to Y (starting from 0) ; if Y > len(a$), then a$ will be padded with spaces (reallocating -; it in dynamic memory if needed). Returns pointer (HL) to resulting +; it in dynamic memory if needed). Returns pointer (HL) to resulting ; string. NULL (0) if no memory for padding. ; @@ -18,89 +18,93 @@ #include once #include once + push namespace core + __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - - dec bc - dec bc ; Number of chars to copy (Len of slice) - - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + + dec bc + dec bc ; Number of chars to copy (Len of slice) + + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + + or a + call nz, __MEM_FREE + + pop hl ; Recover result + ret - or a - call nz, __MEM_FREE + ENDP - pop hl ; Recover result - ret - - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/sub32.asm b/src/arch/zx48k/library-asm/sub32.asm index 5f44ff44a..18e36076d 100644 --- a/src/arch/zx48k/library-asm/sub32.asm +++ b/src/arch/zx48k/library-asm/sub32.asm @@ -1,27 +1,31 @@ -; SUB32 +; SUB32 ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core + __SUB32: - exx - pop bc ; saves return address in BC' - exx + exx + pop bc ; saves return address in BC' + exx + + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret - exx - push bc ; puts return address back - exx - ret + pop namespace diff --git a/src/arch/zx48k/library-asm/subf.asm b/src/arch/zx48k/library-asm/subf.asm index 12cb7c507..1f1482f91 100644 --- a/src/arch/zx48k/library-asm/subf.asm +++ b/src/arch/zx48k/library-asm/subf.asm @@ -11,14 +11,18 @@ ; ------------------------------------------------------------- + push namespace core + __SUBF: ; Subtraction - call __FPSTACK_PUSH2 ; ENTERS B, A - - ; ------------- ROM SUB - rst 28h - defb 01h ; EXCHANGE - defb 03h ; SUB - defb 38h; ; END CALC - - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; ENTERS B, A + + ; ------------- ROM SUB + rst 28h + defb 01h ; EXCHANGE + defb 03h ; SUB + defb 38h; ; END CALC + + jp __FPSTACK_POP + + pop namespace diff --git a/src/arch/zx48k/library-asm/swap32.asm b/src/arch/zx48k/library-asm/swap32.asm index 805bcf57e..d615c7127 100644 --- a/src/arch/zx48k/library-asm/swap32.asm +++ b/src/arch/zx48k/library-asm/swap32.asm @@ -1,8 +1,10 @@ ; Exchanges current DE HL with the ; ones in the stack + push namespace core + __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -12,5 +14,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/table_jump.asm b/src/arch/zx48k/library-asm/table_jump.asm index 4e2c8b3d9..370d2faf8 100644 --- a/src/arch/zx48k/library-asm/table_jump.asm +++ b/src/arch/zx48k/library-asm/table_jump.asm @@ -1,17 +1,21 @@ + push namespace core + JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + + pop namespace diff --git a/src/arch/zx48k/library-asm/tan.asm b/src/arch/zx48k/library-asm/tan.asm index 039039a3e..ef3de4c95 100644 --- a/src/arch/zx48k/library-asm/tan.asm +++ b/src/arch/zx48k/library-asm/tan.asm @@ -1,11 +1,15 @@ #include once + push namespace core + TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH + call __FPSTACK_PUSH + + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC + jp __FPSTACK_POP - jp __FPSTACK_POP + pop namespace diff --git a/src/arch/zx48k/library-asm/u32tofreg.asm b/src/arch/zx48k/library-asm/u32tofreg.asm index c9895b970..19adf7cb7 100644 --- a/src/arch/zx48k/library-asm/u32tofreg.asm +++ b/src/arch/zx48k/library-asm/u32tofreg.asm @@ -1,89 +1,93 @@ #include once + push namespace core + __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) + ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign + ld a, d + or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z + ld c, e ; Returns 00 0000 0000 if ZERO + ret z - push de - push hl + push de + push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) + res 7, e ; Sets the sign bit to 0 (positive) - ret + ret ENDP + pop namespace + diff --git a/src/arch/zx48k/library-asm/usr.asm b/src/arch/zx48k/library-asm/usr.asm index 84d16becd..0b7dad27f 100644 --- a/src/arch/zx48k/library-asm/usr.asm +++ b/src/arch/zx48k/library-asm/usr.asm @@ -2,15 +2,19 @@ ; Result value returns in BC ; We use HL for returning values, su we must ; copy BC into HL before returning -; +; ; The incoming parameter is HL (Address to JUMP) ; #include once + push namespace core + USR: - call CALL_HL - ld h, b - ld l, c - ret + call CALL_HL + ld h, b + ld l, c + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/usr_str.asm b/src/arch/zx48k/library-asm/usr_str.asm index 27451d761..3982652f5 100644 --- a/src/arch/zx48k/library-asm/usr_str.asm +++ b/src/arch/zx48k/library-asm/usr_str.asm @@ -9,42 +9,44 @@ #include once #include once + push namespace core + USR_STR: PROC ex af, af' ; Saves A flag - ld a, h - or l - jr z, USR_ERROR ; a$ = NULL => Invalid Arg + ld a, h + or l + jr z, USR_ERROR ; a$ = NULL => Invalid Arg ld d, h ; Saves HL in DE, for ld e, l ; later usage - ld c, (hl) - inc hl - ld a, (hl) - or c - jr z, USR_ERROR ; a$ = "" => Invalid Arg + ld c, (hl) + inc hl + ld a, (hl) + or c + jr z, USR_ERROR ; a$ = "" => Invalid Arg - inc hl - ld a, (hl) ; Only the 1st char is needed - and 11011111b ; Convert it to UPPER CASE - sub 144 ; CODE(UDG "A") - jr nc, CONT - add a, 144 ; It was a letter - sub 'A' + inc hl + ld a, (hl) ; Only the 1st char is needed + and 11011111b ; Convert it to UPPER CASE + sub 144 ; CODE(UDG "A") + jr nc, CONT + add a, 144 ; It was a letter + sub 'A' LOCAL CONT CONT: - ld l, a - ld h, 0 - add hl, hl - add hl, hl - add hl, hl ; hl = A * 8 - ld bc, (UDG) - add hl, bc - + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, hl ; hl = A * 8 + ld bc, (UDG) + add hl, bc + ;; Now checks if the string must be released ex af, af' ; Recovers A flag or a @@ -54,7 +56,7 @@ CONT: ex de, hl ; Recovers original HL value call __MEM_FREE pop hl - ret + ret USR_ERROR: ex de, hl ; Recovers original HL value @@ -62,9 +64,11 @@ USR_ERROR: or a call nz, __MEM_FREE - ld a, ERROR_InvalidArg - ld (ERR_NR), a - ld hl, 0 - ret - ENDP - + ld a, ERROR_InvalidArg + ld (ERR_NR), a + ld hl, 0 + ret + ENDP + + pop namespace + diff --git a/src/arch/zx48k/library-asm/val.asm b/src/arch/zx48k/library-asm/val.asm index 69c1fc9f1..3096db42b 100644 --- a/src/arch/zx48k/library-asm/val.asm +++ b/src/arch/zx48k/library-asm/val.asm @@ -2,21 +2,23 @@ #include once #include once + push namespace core + VAL: ; Computes VAL(a$) using ROM FP-CALC - ; HL = address of a$ - ; Returns FP number in C ED LH registers - ; A Register = 1 => Free a$ on return - - PROC - - LOCAL STK_STO_S - LOCAL __RET_ZERO - LOCAL ERR_SP - LOCAL STKBOT - LOCAL RECLAIM1 + ; HL = address of a$ + ; Returns FP number in C ED LH registers + ; A Register = 1 => Free a$ on return + + PROC + + LOCAL STK_STO_S + LOCAL __RET_ZERO + LOCAL ERR_SP + LOCAL STKBOT + LOCAL RECLAIM1 LOCAL CH_ADD - LOCAL __VAL_ERROR - LOCAL __VAL_EMPTY + LOCAL __VAL_ERROR + LOCAL __VAL_EMPTY LOCAL SET_MIN RECLAIM1 EQU 6629 @@ -27,93 +29,95 @@ STK_STO_S EQU 2AB2h SET_MIN EQU 16B0h ld d, a ; Preserves A register in DE - ld a, h - or l - jr z, __RET_ZERO ; NULL STRING => Return 0 + ld a, h + or l + jr z, __RET_ZERO ; NULL STRING => Return 0 push de ; Saves A Register (now in D) - push hl ; Not null string. Save its address for later + push hl ; Not null string. Save its address for later - ld c, (hl) - inc hl - ld b, (hl) - inc hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl - ld a, b - or c - jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string + ld a, b + or c + jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string - ex de, hl ; DE = String start + ex de, hl ; DE = String start ld hl, (CH_ADD) push hl - ld hl, (STKBOT) - push hl + ld hl, (STKBOT) + push hl - ld hl, (ERR_SP) - push hl + ld hl, (ERR_SP) + push hl ;; Now put our error handler on ERR_SP - ld hl, __VAL_ERROR - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl + ld hl, __VAL_ERROR + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl - call STK_STO_S ; Enter it on the stack + call STK_STO_S ; Enter it on the stack - ld b, 1Dh ; "VAL" - rst 28h ; ROM CALC - defb 1Dh ; VAL - defb 38h ; END CALC + ld b, 1Dh ; "VAL" + rst 28h ; ROM CALC + defb 1Dh ; VAL + defb 38h ; END CALC - pop hl ; Discards our current error handler - pop hl - ld (ERR_SP), hl ; Restores ERR_SP + pop hl ; Discards our current error handler + pop hl + ld (ERR_SP), hl ; Restores ERR_SP - pop de ; old STKBOT - ld hl, (STKBOT) ; current SKTBOT - call RECLAIM1 ; Recover unused space + pop de ; old STKBOT + ld hl, (STKBOT) ; current SKTBOT + call RECLAIM1 ; Recover unused space pop hl ; Discards old CH_ADD value - pop hl ; String pointer - pop af ; Deletion flag - or a - call nz, __MEM_FREE ; Frees string content before returning + pop hl ; String pointer + pop af ; Deletion flag + or a + call nz, __MEM_FREE ; Frees string content before returning ld a, ERROR_Ok ; Sets OK in the result ld (ERR_NR), a - jp __FPSTACK_POP ; Recovers result and return from there + jp __FPSTACK_POP ; Recovers result and return from there __VAL_ERROR: ; Jumps here on ERROR - pop hl - ld (ERR_SP), hl ; Restores ERR_SP + pop hl + ld (ERR_SP), hl ; Restores ERR_SP - ld hl, (STKBOT) ; current SKTBOT - pop de ; old STKBOT + ld hl, (STKBOT) ; current SKTBOT + pop de ; old STKBOT pop hl ld (CH_ADD), hl ; Recovers old CH_ADD call 16B0h ; Resets temporary areas after an error __VAL_EMPTY: ; Jumps here on empty string - pop hl ; Recovers initial string address - pop af ; String flag: If not 0 => it's temporary - or a - call nz, __MEM_FREE ; Frees "" string + pop hl ; Recovers initial string address + pop af ; String flag: If not 0 => it's temporary + or a + call nz, __MEM_FREE ; Frees "" string __RET_ZERO: ; Returns 0 Floating point on error - ld a, ERROR_InvalidArg - ld (ERR_NR), a + ld a, ERROR_InvalidArg + ld (ERR_NR), a + + xor a + ld b, a + ld c, a + ld d, b + ld e, c + ret - xor a - ld b, a - ld c, a - ld d, b - ld e, c - ret + ENDP - ENDP + pop namespace diff --git a/src/arch/zx48k/library-asm/xor32.asm b/src/arch/zx48k/library-asm/xor32.asm index 3e4116b23..7f6fba94e 100644 --- a/src/arch/zx48k/library-asm/xor32.asm +++ b/src/arch/zx48k/library-asm/xor32.asm @@ -5,6 +5,8 @@ #include once + push namespace core + __XOR32: ld a, h or l @@ -22,3 +24,5 @@ __XOR32: ld h, c jp __XOR8 + pop namespace + diff --git a/src/arch/zx48k/library-asm/xor8.asm b/src/arch/zx48k/library-asm/xor8.asm index 035372454..683ef2553 100644 --- a/src/arch/zx48k/library-asm/xor8.asm +++ b/src/arch/zx48k/library-asm/xor8.asm @@ -4,13 +4,15 @@ ; __FASTCALL__ version (operands: A, H) ; Performs 8bit xor 8bit and returns the boolean + push namespace core + __XOR16: - ld a, h - or l + ld a, h + or l ld h, a - ld a, d - or e + ld a, d + or e __XOR8: sub 1 @@ -21,5 +23,7 @@ __XOR8: sub 1 sbc a, a ; a = 00h or FFh xor l - ret + ret + + pop namespace diff --git a/src/arch/zx48k/library-asm/xorf.asm b/src/arch/zx48k/library-asm/xorf.asm index aaabcb861..a92d0d984 100644 --- a/src/arch/zx48k/library-asm/xorf.asm +++ b/src/arch/zx48k/library-asm/xorf.asm @@ -12,24 +12,28 @@ ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core + __XORF: ; A XOR B - call __FPSTACK_PUSH2 - - ; A XOR B == A ^ ¬B v ¬A ^ B - rst 28h - defb 0C0h ; STORE 0 - defb 02h ; DELETE - defb 31h ; DUP - defb 30h ; NOT A - defb 0E0h ; Recall 0 - defb 08h ; AND - defb 01h ; SWAP - defb 0E0h ; Recall 0 - defb 30h ; NOT B - defb 08h ; AND - defb 07h ; OR - defb 38h ; END CALC - - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + + ; A XOR B == A ^ ¬B v ¬A ^ B + rst 28h + defb 0C0h ; STORE 0 + defb 02h ; DELETE + defb 31h ; DUP + defb 30h ; NOT A + defb 0E0h ; Recall 0 + defb 08h ; AND + defb 01h ; SWAP + defb 0E0h ; Recall 0 + defb 30h ; NOT B + defb 08h ; AND + defb 07h ; OR + defb 38h ; END CALC + + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + + pop namespace diff --git a/tests/functional/00.asm b/tests/functional/00.asm index c2be5294d..176358cf6 100644 --- a/tests/functional/00.asm +++ b/tests/functional/00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/02.asm b/tests/functional/02.asm index 31ac0f037..c021353d3 100644 --- a/tests/functional/02.asm +++ b/tests/functional/02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/03.asm b/tests/functional/03.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/03.asm +++ b/tests/functional/03.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/04.asm b/tests/functional/04.asm index 31ac0f037..c021353d3 100644 --- a/tests/functional/04.asm +++ b/tests/functional/04.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/05.asm b/tests/functional/05.asm index f7953b26f..ecc7554b6 100644 --- a/tests/functional/05.asm +++ b/tests/functional/05.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -37,14 +37,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/053opt.asm b/tests/functional/053opt.asm index d774c995d..0a3a30992 100644 --- a/tests/functional/053opt.asm +++ b/tests/functional/053opt.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _subeEgg: DEFB 00 _sail: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_sail) dec a jp nz, __LABEL1 @@ -37,21 +37,21 @@ __MAIN_PROGRAM__: ld a, (40044) ld hl, (40012 - 1) sub h - call __ABS8 + call core.__ABS8 push af ld h, 16 pop af - call __LTI8 + call core.__LTI8 or a jp z, __LABEL7 ld a, (40011) ld hl, (40043 - 1) sub h - call __ABS8 + call core.__ABS8 push af ld h, 20 pop af - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL__enddispara __LABEL9: @@ -60,9 +60,9 @@ __LABEL5: __LABEL3: __LABEL1: jp __LABEL__enddispara -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -75,21 +75,24 @@ __LABEL__enddispara: ld hl, 0 ld b, h ld c, l - jp __END_PROGRAM + jp core.__END_PROGRAM ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/abs8.asm" ; Returns absolute value for 8 bit signed integer ; + push namespace core __ABS8: - or a - ret p - neg - ret + or a + ret p + neg + ret + pop namespace #line 55 "053opt.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -107,6 +110,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 56 "053opt.bas" END diff --git a/tests/functional/06.asm b/tests/functional/06.asm index 3a3f76ead..9d3ec0347 100644 --- a/tests/functional/06.asm +++ b/tests/functional/06.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -32,14 +32,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/07.asm b/tests/functional/07.asm index 19007dd1f..2f760373c 100644 --- a/tests/functional/07.asm +++ b/tests/functional/07.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -51,14 +51,14 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/08.asm b/tests/functional/08.asm index 3e84a890e..4dca2e900 100644 --- a/tests/functional/08.asm +++ b/tests/functional/08.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/09.asm b/tests/functional/09.asm index 3f9ca420e..d85486448 100644 --- a/tests/functional/09.asm +++ b/tests/functional/09.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -36,14 +36,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/10.asm b/tests/functional/10.asm index fc81e5b1c..d408d38c1 100644 --- a/tests/functional/10.asm +++ b/tests/functional/10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -28,14 +28,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/11.asm b/tests/functional/11.asm index 1ee9e6261..e5e9cd206 100644 --- a/tests/functional/11.asm +++ b/tests/functional/11.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -57,14 +57,14 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/12.asm b/tests/functional/12.asm index 6e1bab162..43dd0406a 100644 --- a/tests/functional/12.asm +++ b/tests/functional/12.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__100: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/13.asm b/tests/functional/13.asm index ee88a4eb3..a09e03832 100644 --- a/tests/functional/13.asm +++ b/tests/functional/13.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__mylabel: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/15.asm b/tests/functional/15.asm index 593641118..c73ef6ec2 100644 --- a/tests/functional/15.asm +++ b/tests/functional/15.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a inc a @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/16.asm b/tests/functional/16.asm index 78e06245a..05088071e 100644 --- a/tests/functional/16.asm +++ b/tests/functional/16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a inc a @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/17.asm b/tests/functional/17.asm index 52fd0ae32..8876ea122 100644 --- a/tests/functional/17.asm +++ b/tests/functional/17.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a inc a @@ -32,9 +32,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/18.asm b/tests/functional/18.asm index af2adc314..88a5c437c 100644 --- a/tests/functional/18.asm +++ b/tests/functional/18.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _c: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a ld a, 2 @@ -36,9 +36,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/19.asm b/tests/functional/19.asm index 8771d80cc..dbe977f41 100644 --- a/tests/functional/19.asm +++ b/tests/functional/19.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,80 +8,80 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call SIN + call core.SIN ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call COS + call core.COS ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call TAN + call core.TAN ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call ASIN + call core.ASIN ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call ACOS + call core.ACOS ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call ATAN + call core.ATAN ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call LN + call core.LN ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call EXP + call core.EXP ld hl, _x - call __STOREF + call core.__STOREF ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call SQRT + call core.SQRT ld hl, _x - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -96,12 +96,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -116,116 +117,137 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/acos.asm" + push namespace core ACOS: ; Computes ACOS using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 23h ; ACOS - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 23h ; ACOS + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 71 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/asin.asm" + push namespace core ASIN: ; Computes ASIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 22h ; ASIN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 22h ; ASIN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 72 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/atan.asm" + push namespace core ATAN: ; Computes ATAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 24h ; ATAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 24h ; ATAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 73 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cos.asm" + push namespace core COS: ; Computes COS using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 20h ; COS - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 20h ; COS + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 74 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/exp.asm" + push namespace core EXP: ; Computes e^n using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 26h ; E^n - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 26h ; E^n + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 75 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/logn.asm" + push namespace core LN: ; Computes Ln(x) using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 20h ; 25h - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 20h ; 25h + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 76 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 77 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sqrt.asm" + push namespace core SQRT: ; Computes SQRT(x) using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 28h ; SQRT - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 28h ; SQRT + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 78 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 79 "19.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 80 "19.bas" END diff --git a/tests/functional/20.asm b/tests/functional/20.asm index bcc147424..3e83dc90a 100644 --- a/tests/functional/20.asm +++ b/tests/functional/20.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/21.asm b/tests/functional/21.asm index 56732e36d..6dcaf7ae1 100644 --- a/tests/functional/21.asm +++ b/tests/functional/21.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) ld hl, _a - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,30 +45,32 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 22 "21.bas" END diff --git a/tests/functional/22.asm b/tests/functional/22.asm index 5bb12239d..d3b3be994 100644 --- a/tests/functional/22.asm +++ b/tests/functional/22.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) neg ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/25.asm b/tests/functional/25.asm index 0bf43180d..0777fda11 100644 --- a/tests/functional/25.asm +++ b/tests/functional/25.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _c: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, 5 ld hl, 6553 ld (_a), hl ld (_a + 2), de ld hl, (_a) ld de, (_a + 2) - call __NOT32 + call core.__NOT32 ld (_c), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,13 +51,15 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; 32 bit logical NOT ; ------------------------------------------------------------- + push namespace core __NOT32: ; A = ¬A - ld a, d - or e - or h - or l - sub 1 ; Gives CARRY only if 0 - sbc a, a; Gives 0 if not carry, FF otherwise - ret + ld a, d + or e + or h + or l + sub 1 ; Gives CARRY only if 0 + sbc a, a; Gives 0 if not carry, FF otherwise + ret + pop namespace #line 25 "25.bas" END diff --git a/tests/functional/26.asm b/tests/functional/26.asm index 657fb3fb9..b61296ed4 100644 --- a/tests/functional/26.asm +++ b/tests/functional/26.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 7 ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/27.asm b/tests/functional/27.asm index a51344d15..d9402a6ad 100644 --- a/tests/functional/27.asm +++ b/tests/functional/27.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _b - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -129,6 +129,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -158,6 +159,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -283,9 +285,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -293,37 +296,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -336,90 +340,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -489,94 +495,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -598,132 +606,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -748,5 +761,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 29 "27.bas" END diff --git a/tests/functional/28.asm b/tests/functional/28.asm index e380f30a4..086c137a3 100644 --- a/tests/functional/28.asm +++ b/tests/functional/28.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, (_a) - call __STRLEN + call core.__STRLEN ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -134,6 +134,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -163,6 +164,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -288,9 +290,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -298,37 +301,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -341,90 +345,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -494,94 +500,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -603,132 +611,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -753,19 +766,22 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 32 "28.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 33 "28.bas" END diff --git a/tests/functional/29.asm b/tests/functional/29.asm index 45832bea7..fd2222ab3 100644 --- a/tests/functional/29.asm +++ b/tests/functional/29.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,45 +8,45 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld de, (_a) ld hl, (_a) - call __ADDSTR + call core.__ADDSTR push hl - call __STRLEN + call core.__STRLEN ex (sp), hl - call __MEM_FREE + call core.__MEM_FREE pop hl ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -189,9 +189,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -199,37 +200,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -239,94 +241,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 38 "29.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -403,6 +407,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -432,6 +437,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -504,90 +510,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -609,132 +617,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -759,114 +772,119 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 39 "29.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 40 "29.bas" END diff --git a/tests/functional/30.asm b/tests/functional/30.asm index b0b5d2cf2..9017290e2 100644 --- a/tests/functional/30.asm +++ b/tests/functional/30.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/31.asm b/tests/functional/31.asm index 7f24ac666..fdd331056 100644 --- a/tests/functional/31.asm +++ b/tests/functional/31.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -41,13 +41,13 @@ _test: ld ix, 0 add ix, sp ld hl, _a + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __ADDF + call core.__ADDF ld hl, _a - call __STOREF + call core.__STOREF _test__leave: ld sp, ix pop ix @@ -58,12 +58,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -78,19 +79,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -100,19 +102,22 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 33 "31.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -133,32 +138,35 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 34 "31.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 35 "31.bas" END diff --git a/tests/functional/32.asm b/tests/functional/32.asm index 323d0c2d7..cb8f22e6b 100644 --- a/tests/functional/32.asm +++ b/tests/functional/32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/33.asm b/tests/functional/33.asm index 6c692044c..b1b4b05f7 100644 --- a/tests/functional/33.asm +++ b/tests/functional/33.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/34.asm b/tests/functional/34.asm index 95e114670..2d17107bc 100644 --- a/tests/functional/34.asm +++ b/tests/functional/34.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -40,7 +40,7 @@ _test: add ix, sp ld a, (ix+5) inc a - call __U8TOFREG + call core.__U8TOFREG _test__leave: ld sp, ix pop ix @@ -52,95 +52,99 @@ _test__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 32 "34.bas" END diff --git a/tests/functional/35.asm b/tests/functional/35.asm index c6e6f9373..1885eb236 100644 --- a/tests/functional/35.asm +++ b/tests/functional/35.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,7 +44,7 @@ _test: push hl inc sp ld a, (ix+5) - call __U8TOFREG + call core.__U8TOFREG push bc push de push af @@ -52,8 +52,8 @@ _test: pop hl ld de, -5 add hl, de - call __PLOADF - call __ADDF + call core.__PLOADF + call core.__ADDF _test__leave: ld sp, ix pop ix @@ -68,12 +68,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -88,19 +89,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -110,13 +112,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 45 "35.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -128,6 +132,7 @@ __ADDF: ; Addition ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -138,114 +143,121 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 46 "35.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 47 "35.bas" END diff --git a/tests/functional/36.asm b/tests/functional/36.asm index 7a74bb58d..6cc853424 100644 --- a/tests/functional/36.asm +++ b/tests/functional/36.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 push af call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,7 +47,7 @@ _test: push hl inc sp ld a, (ix+5) - call __U8TOFREG + call core.__U8TOFREG push bc push de push af @@ -55,8 +55,8 @@ _test: pop hl ld de, -5 add hl, de - call __PLOADF - call __ADDF + call core.__PLOADF + call core.__ADDF _test__leave: ld sp, ix pop ix @@ -71,12 +71,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -91,19 +92,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -113,13 +115,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 48 "36.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -131,6 +135,7 @@ __ADDF: ; Addition ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -141,114 +146,121 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 49 "36.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 50 "36.bas" END diff --git a/tests/functional/37.asm b/tests/functional/37.asm index b0a5add3c..aac4c00cd 100644 --- a/tests/functional/37.asm +++ b/tests/functional/37.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 push af call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,7 +47,7 @@ _test: push hl inc sp ld a, (ix+5) - call __U8TOFREG + call core.__U8TOFREG push bc push de push af @@ -55,8 +55,8 @@ _test: pop hl ld de, -5 add hl, de - call __PLOADF - call __ADDF + call core.__PLOADF + call core.__ADDF _test__leave: ld sp, ix pop ix @@ -71,12 +71,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -91,19 +92,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -113,13 +115,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 48 "37.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -131,6 +135,7 @@ __ADDF: ; Addition ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -141,114 +146,121 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 49 "37.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 50 "37.bas" END diff --git a/tests/functional/38.asm b/tests/functional/38.asm index 883febe40..17fd603cb 100644 --- a/tests/functional/38.asm +++ b/tests/functional/38.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 push af call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,7 +47,7 @@ _test: push hl inc sp ld a, (ix+5) - call __U8TOFREG + call core.__U8TOFREG push bc push de push af @@ -55,8 +55,8 @@ _test: pop hl ld de, -5 add hl, de - call __PLOADF - call __ADDF + call core.__PLOADF + call core.__ADDF _test__leave: ld sp, ix pop ix @@ -71,12 +71,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -91,19 +92,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -113,13 +115,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 48 "38.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -131,6 +135,7 @@ __ADDF: ; Addition ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -141,114 +146,121 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 49 "38.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 50 "38.bas" END diff --git a/tests/functional/39.asm b/tests/functional/39.asm index d359798dc..98f26ffa8 100644 --- a/tests/functional/39.asm +++ b/tests/functional/39.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 push af call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,7 +54,7 @@ _test: ldir ld a, (ix+5) add a, (ix-1) - call __U8TOFREG + call core.__U8TOFREG _test__leave: ld sp, ix pop ix @@ -66,96 +66,100 @@ _test__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 46 "39.bas" __LABEL0: DEFB 02h diff --git a/tests/functional/40.asm b/tests/functional/40.asm index f2104701a..59eb21dce 100644 --- a/tests/functional/40.asm +++ b/tests/functional/40.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,15 +51,15 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 3 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld a, (ix+5) - call __U8TOFREG + call core.__U8TOFREG _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -145,6 +145,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -174,6 +175,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -239,9 +241,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -249,37 +252,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -292,90 +296,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -389,25 +395,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -422,6 +430,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -471,7 +480,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 47 "40.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -541,187 +551,193 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 48 "40.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 49 "40.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/41.asm b/tests/functional/41.asm index 073765d6a..230e9f03b 100644 --- a/tests/functional/41.asm +++ b/tests/functional/41.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: @@ -31,16 +31,16 @@ _b.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b.__DATA__ + 1) ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/42.asm b/tests/functional/42.asm index bebedb9b7..e2615c0b0 100644 --- a/tests/functional/42.asm +++ b/tests/functional/42.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 3 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) inc hl @@ -62,7 +62,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -148,6 +148,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -177,6 +178,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -242,9 +244,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -252,37 +255,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -295,90 +299,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -392,25 +398,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -425,6 +433,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -474,7 +483,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 50 "42.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -544,94 +554,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 51 "42.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/43.asm b/tests/functional/43.asm index fed04cf5d..d7f762b3e 100644 --- a/tests/functional/43.asm +++ b/tests/functional/43.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 3 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld a, (ix+5) push af ld l, (ix-2) @@ -59,13 +59,13 @@ _test: inc hl pop af add a, (hl) - call __U8TOFREG + call core.__U8TOFREG _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -151,6 +151,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -180,6 +181,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -245,9 +247,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -255,37 +258,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -298,90 +302,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -395,25 +401,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -428,6 +436,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -477,7 +486,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 53 "43.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -547,187 +557,193 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 54 "43.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 55 "43.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/44.asm b/tests/functional/44.asm index 0557cc5cc..81625180e 100644 --- a/tests/functional/44.asm +++ b/tests/functional/44.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: @@ -41,16 +41,16 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b.__DATA__ + 7) ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/45.asm b/tests/functional/45.asm index 34017dfab..9eb42770c 100644 --- a/tests/functional/45.asm +++ b/tests/functional/45.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,7 +53,7 @@ _test: ld hl, -5 ld de, __LABEL0 ld bc, 12 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-3) ld h, (ix-2) ld de, 7 @@ -65,7 +65,7 @@ _test__leave: exx ld l, (ix-3) ld h, (ix-2) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -147,6 +147,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -176,6 +177,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -241,9 +243,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -251,37 +254,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -294,90 +298,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -391,25 +397,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -424,6 +432,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -473,7 +482,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 49 "45.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -543,94 +553,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 50 "45.bas" __LABEL0: DEFB 01h diff --git a/tests/functional/46.asm b/tests/functional/46.asm index 43aff2aa4..91846271c 100644 --- a/tests/functional/46.asm +++ b/tests/functional/46.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _c: @@ -43,8 +43,8 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a ld a, 3 @@ -57,15 +57,15 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _b - call __ARRAY + call core.__ARRAY ld a, (hl) ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -92,81 +92,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -174,16 +177,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -202,6 +205,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 32 "46.bas" END diff --git a/tests/functional/47.asm b/tests/functional/47.asm index da75860c3..0f51381a8 100644 --- a/tests/functional/47.asm +++ b/tests/functional/47.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -6 ld de, __LABEL0 ld bc, 12 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld (ix-1), 1 ld (ix-2), 3 ld a, (ix-2) @@ -67,7 +67,7 @@ _test: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY ld a, (hl) ld (ix-1), a _test__leave: @@ -75,7 +75,7 @@ _test__leave: exx ld l, (ix-4) ld h, (ix-3) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -99,81 +99,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -181,16 +184,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -209,7 +212,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 59 "47.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -286,6 +290,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -315,6 +320,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -380,9 +386,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -390,37 +397,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -433,90 +441,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -530,25 +540,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -563,6 +575,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -612,7 +625,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 60 "47.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -682,94 +696,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 61 "47.bas" __LABEL0: DEFB 01h diff --git a/tests/functional/48.asm b/tests/functional/48.asm index 869f5419b..8a2e5f869 100644 --- a/tests/functional/48.asm +++ b/tests/functional/48.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, (_a) push hl ld hl, 2 @@ -39,16 +39,16 @@ __MAIN_PROGRAM__: ld hl, 2 push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -142,6 +142,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -171,6 +172,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -296,9 +298,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -306,37 +309,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -349,90 +353,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -502,94 +508,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -611,132 +619,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -761,6 +774,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 40 "48.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -769,30 +783,32 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 41 "48.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -812,84 +828,88 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 42 "48.bas" END diff --git a/tests/functional/49.asm b/tests/functional/49.asm index 20c7a96dc..d5b863296 100644 --- a/tests/functional/49.asm +++ b/tests/functional/49.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, (_a) push hl ld hl, 2 @@ -39,16 +39,16 @@ __MAIN_PROGRAM__: ld hl, 3 push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -142,6 +142,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -171,6 +172,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -296,9 +298,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -306,37 +309,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -349,90 +353,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -502,94 +508,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -611,132 +619,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -761,6 +774,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 40 "49.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -769,30 +783,32 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 41 "49.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -812,84 +828,88 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 42 "49.bas" END diff --git a/tests/functional/52.asm b/tests/functional/52.asm index 4d829a682..6e9bf699e 100644 --- a/tests/functional/52.asm +++ b/tests/functional/52.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -60,8 +60,8 @@ __LABEL1: DEFW 0001h DEFW 0004h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 12 ld b, h ld c, l @@ -71,9 +71,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/54.asm b/tests/functional/54.asm index d47284043..364027545 100644 --- a/tests/functional/54.asm +++ b/tests/functional/54.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 04h _b: @@ -41,16 +41,16 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b.__DATA__ + 7), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/55.asm b/tests/functional/55.asm index a676a577c..2f3a30edb 100644 --- a/tests/functional/55.asm +++ b/tests/functional/55.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 04h _b: @@ -41,8 +41,8 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld l, a ld h, 0 @@ -50,15 +50,15 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, _b - call __ARRAY + call core.__ARRAY ld a, (_a) ld (hl), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -85,81 +85,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -167,16 +170,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -195,6 +198,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 27 "55.bas" END diff --git a/tests/functional/60.asm b/tests/functional/60.asm index 765177b76..0357e7703 100644 --- a/tests/functional/60.asm +++ b/tests/functional/60.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/61.asm b/tests/functional/61.asm index 765177b76..0357e7703 100644 --- a/tests/functional/61.asm +++ b/tests/functional/61.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/63.asm b/tests/functional/63.asm index 3731427db..0009c93ff 100644 --- a/tests/functional/63.asm +++ b/tests/functional/63.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 push af call _test @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/64.asm b/tests/functional/64.asm index 0e0b69d18..f82b387dc 100644 --- a/tests/functional/64.asm +++ b/tests/functional/64.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/65.asm b/tests/functional/65.asm index 4d08c39bd..ea1e4ae03 100644 --- a/tests/functional/65.asm +++ b/tests/functional/65.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 call _test ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/66.asm b/tests/functional/66.asm index 0aafabf00..ae94fcd2f 100644 --- a/tests/functional/66.asm +++ b/tests/functional/66.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 082h ld de, 00000h ld bc, 00000h @@ -34,9 +34,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/70.asm b/tests/functional/70.asm index 3ac21863a..96bfbbfc4 100644 --- a/tests/functional/70.asm +++ b/tests/functional/70.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,46 +8,46 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 10 ld (_b), a - call __U8TOFREG - call SQRT - call EXP - call LN + call core.__U8TOFREG + call core.SQRT + call core.EXP + call core.LN res 7, e - call TAN - call COS - call SIN + call core.TAN + call core.COS + call core.SIN ld hl, _a - call __STOREF + call core.__STOREF ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -62,12 +62,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -82,108 +83,116 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/cos.asm" + push namespace core COS: ; Computes COS using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 20h ; COS - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 20h ; COS + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 35 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/exp.asm" + push namespace core EXP: ; Computes e^n using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 26h ; E^n - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 26h ; E^n + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 36 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -200,138 +209,151 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 37 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/logn.asm" + push namespace core LN: ; Computes Ln(x) using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 20h ; 25h - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 20h ; 25h + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 38 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 39 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sqrt.asm" + push namespace core SQRT: ; Computes SQRT(x) using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 28h ; SQRT - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 28h ; SQRT + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 40 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 41 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 42 "70.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 43 "70.bas" END diff --git a/tests/functional/abs.asm b/tests/functional/abs.asm index f865b995b..fa5311e4e 100644 --- a/tests/functional/abs.asm +++ b/tests/functional/abs.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a neg @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/abs16.asm b/tests/functional/abs16.asm index ba63dc11c..61fa23e1a 100644 --- a/tests/functional/abs16.asm +++ b/tests/functional/abs16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) - call __ABS16 + call core.__ABS16 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,18 +47,20 @@ __END_PROGRAM: ; HL = value #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/abs16.asm" #line 20 "abs16.bas" END diff --git a/tests/functional/abs32.asm b/tests/functional/abs32.asm index 9ba553655..1b064b8a8 100644 --- a/tests/functional/abs32.asm +++ b/tests/functional/abs32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) ld de, (_b + 2) - call __ABS32 + call core.__ABS32 ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,28 +48,30 @@ __END_PROGRAM: ; 16 bit signed integer abs value ; HL = value #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/abs32.asm" #line 22 "abs32.bas" END diff --git a/tests/functional/add16.asm b/tests/functional/add16.asm index 3ac8ce55e..6203b798a 100644 --- a/tests/functional/add16.asm +++ b/tests/functional/add16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld (_b), hl ld hl, (_a) @@ -41,9 +41,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add16a.asm b/tests/functional/add16a.asm index 0bf330b3f..e8e5193c5 100644 --- a/tests/functional/add16a.asm +++ b/tests/functional/add16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_a) ld hl, (_a) add hl, de @@ -32,9 +32,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add16b.asm b/tests/functional/add16b.asm index e14d38ef7..1d775cc66 100644 --- a/tests/functional/add16b.asm +++ b/tests/functional/add16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_a) ld hl, (_a) add hl, de @@ -39,9 +39,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add32.asm b/tests/functional/add32.asm index b4f29b148..e0377999e 100644 --- a/tests/functional/add32.asm +++ b/tests/functional/add32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld (_b), hl @@ -65,9 +65,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add32a.asm b/tests/functional/add32a.asm index ef5ad546c..9a27029c1 100644 --- a/tests/functional/add32a.asm +++ b/tests/functional/add32a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld bc, (_a) @@ -41,9 +41,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add32b.asm b/tests/functional/add32b.asm index 90897d4f3..d3e96712a 100644 --- a/tests/functional/add32b.asm +++ b/tests/functional/add32b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld bc, (_a) @@ -56,9 +56,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add8.asm b/tests/functional/add8.asm index fe0d6b386..c1bbd450c 100644 --- a/tests/functional/add8.asm +++ b/tests/functional/add8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -41,9 +41,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add8a.asm b/tests/functional/add8a.asm index c3bb907c2..157a68b6f 100644 --- a/tests/functional/add8a.asm +++ b/tests/functional/add8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a - 1) ld a, (_a) add a, h @@ -32,9 +32,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/add8b.asm b/tests/functional/add8b.asm index abec2eb83..46d699732 100644 --- a/tests/functional/add8b.asm +++ b/tests/functional/add8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a - 1) ld a, (_a) add a, h @@ -38,9 +38,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/addf16.asm b/tests/functional/addf16.asm index 1d23c872d..c1681d6cd 100644 --- a/tests/functional/addf16.asm +++ b/tests/functional/addf16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld (_b), hl @@ -65,9 +65,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/addf16a.asm b/tests/functional/addf16a.asm index ef5ad546c..9a27029c1 100644 --- a/tests/functional/addf16a.asm +++ b/tests/functional/addf16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld bc, (_a) @@ -41,9 +41,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/addf16b.asm b/tests/functional/addf16b.asm index 562bc4e24..f96b66114 100644 --- a/tests/functional/addf16b.asm +++ b/tests/functional/addf16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld bc, (_a) @@ -56,9 +56,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/addstr.asm b/tests/functional/addstr.asm index b6fecb581..2cefa329a 100644 --- a/tests/functional/addstr.asm +++ b/tests/functional/addstr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,63 +8,63 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, (_a) - call __ADDSTR + call core.__ADDSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld de, __LABEL1 ld hl, (_a) - call __ADDSTR + call core.__ADDSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld de, (_a) ld hl, __LABEL0 - call __ADDSTR + call core.__ADDSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld de, (_a) ld hl, __LABEL1 - call __ADDSTR + call core.__ADDSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld de, (_a) ld hl, (_a) - call __ADDSTR + call core.__ADDSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,119 +262,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 52 "addstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -438,6 +444,7 @@ __STORE_STR2: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -467,6 +474,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -479,197 +487,203 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 53 "addstr.bas" END diff --git a/tests/functional/aloadstr0.asm b/tests/functional/aloadstr0.asm index f404e0f0f..d6366f987 100644 --- a/tests/functional/aloadstr0.asm +++ b/tests/functional/aloadstr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -235,19 +235,19 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a.__DATA__ + 2) - call __LOADSTR + call core.__LOADSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -321,6 +321,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -350,6 +351,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -415,9 +417,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -425,37 +428,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -468,125 +472,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 22 "aloadstr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -663,118 +671,122 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 23 "aloadstr0.bas" END diff --git a/tests/functional/aloadstr1.asm b/tests/functional/aloadstr1.asm index 82ade813d..6b1c87e8d 100644 --- a/tests/functional/aloadstr1.asm +++ b/tests/functional/aloadstr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00 _b: @@ -237,24 +237,24 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_c) ld l, a ld h, 0 push hl ld hl, _a - call __ARRAY - call __ILOADSTR + call core.__ARRAY + call core.__ILOADSTR ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -281,81 +281,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -363,16 +366,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -391,7 +394,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 27 "aloadstr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -457,6 +461,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -486,6 +491,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -551,9 +557,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -561,37 +568,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -604,125 +612,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 28 "aloadstr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -799,118 +811,122 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 29 "aloadstr1.bas" END diff --git a/tests/functional/and16.asm b/tests/functional/and16.asm index e79dd5e88..877e7075b 100644 --- a/tests/functional/and16.asm +++ b/tests/functional/and16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) xor a ld (_b), a @@ -40,14 +40,14 @@ __MAIN_PROGRAM__: ld (_b), a ld de, (_a) ld hl, (_a) - call __AND16 + call core.__AND16 ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -62,12 +62,14 @@ __END_PROGRAM: ; result in Accumulator (0 False, not 0 True) ; __FASTCALL__ version (operands: DE, HL) ; Performs 16bit and 16bit and returns the boolean + push namespace core __AND16: - ld a, h - or l - ret z - ld a, d - or e - ret + ld a, h + or l + ret z + ld a, d + or e + ret + pop namespace #line 35 "and16.bas" END diff --git a/tests/functional/and32.asm b/tests/functional/and32.asm index 70e5a898a..63cbda2a8 100644 --- a/tests/functional/and32.asm +++ b/tests/functional/and32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_b), a ld hl, (_a + 2) @@ -32,7 +32,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __AND32 + call core.__AND32 ld (_b), a xor a ld (_b), a @@ -42,7 +42,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __AND32 + call core.__AND32 ld (_b), a ld hl, (_a + 2) push hl @@ -50,14 +50,14 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __AND32 + call core.__AND32 ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -72,6 +72,7 @@ __END_PROGRAM: ; Performs 32bit and 32bit and returns the boolean ; result in Accumulator (0 False, not 0 True) ; First operand in DE,HL 2nd operand into the stack + push namespace core __AND32: ld a, l or h @@ -85,7 +86,8 @@ __AND32: or e or h or l -#line 26 "/zxbasic/src/arch/zx48k/library-asm/and32.asm" +#line 28 "/zxbasic/src/arch/zx48k/library-asm/and32.asm" ret + pop namespace #line 45 "and32.bas" END diff --git a/tests/functional/and8.asm b/tests/functional/and8.asm index 43d439b84..9f0f8ac53 100644 --- a/tests/functional/and8.asm +++ b/tests/functional/and8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) xor a ld (_b), a @@ -44,9 +44,9 @@ __LABEL0: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arden2.asm b/tests/functional/arden2.asm index 4148e2239..40fb4c205 100644 --- a/tests/functional/arden2.asm +++ b/tests/functional/arden2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,48 +8,48 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _result: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_c) ld a, l push af ld hl, 1 - call CHR + call core.CHR ex de, hl ld hl, (_result) push de - call __ADDSTR + call core.__ADDSTR ex (sp), hl - call __MEM_FREE + call core.__MEM_FREE pop hl ex de, hl ld hl, _result - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -125,6 +125,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -154,6 +155,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -219,9 +221,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -229,37 +232,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -272,142 +276,146 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/chr.asm" + push namespace core CHR: ; Returns HL = Pointer to STRING (NULL if no memory) - ; Requires alloc.asm for dynamic memory heap. - ; Parameters: HL = Number of bytes to insert (already push onto the stack) - ; STACK => parameters (16 bit, only the High byte is considered) - ; Used registers A, A', BC, DE, HL, H'L' - PROC - LOCAL __POPOUT - LOCAL TMP + ; Requires alloc.asm for dynamic memory heap. + ; Parameters: HL = Number of bytes to insert (already push onto the stack) + ; STACK => parameters (16 bit, only the High byte is considered) + ; Used registers A, A', BC, DE, HL, H'L' + PROC + LOCAL __POPOUT + LOCAL TMP TMP EQU 23629 ; (DEST System variable) - ld a, h - or l - ret z ; If Number of parameters is ZERO, return NULL STRING - ld b, h - ld c, l - pop hl ; Return address - ld (TMP), hl - push bc - inc bc - inc bc ; BC = BC + 2 => (2 bytes for the length number) - call __MEM_ALLOC - pop bc - ld d, h - ld e, l ; Saves HL in DE - ld a, h - or l - jr z, __POPOUT ; No Memory, return - ld (hl), c - inc hl - ld (hl), b - inc hl + ld a, h + or l + ret z ; If Number of parameters is ZERO, return NULL STRING + ld b, h + ld c, l + pop hl ; Return address + ld (TMP), hl + push bc + inc bc + inc bc ; BC = BC + 2 => (2 bytes for the length number) + call __MEM_ALLOC + pop bc + ld d, h + ld e, l ; Saves HL in DE + ld a, h + or l + jr z, __POPOUT ; No Memory, return + ld (hl), c + inc hl + ld (hl), b + inc hl __POPOUT: ; Removes out of the stack every byte and return - ; If Zero Flag is set, don't store bytes in memory - ex af, af' ; Save Zero Flag - ld a, b - or c - jr z, __CHR_END - dec bc - pop af ; Next byte - ex af, af' ; Recovers Zero flag - jr z, __POPOUT - ex af, af' ; Saves Zero flag - ld (hl), a - inc hl - ex af, af' ; Recovers Zero Flag - jp __POPOUT + ; If Zero Flag is set, don't store bytes in memory + ex af, af' ; Save Zero Flag + ld a, b + or c + jr z, __CHR_END + dec bc + pop af ; Next byte + ex af, af' ; Recovers Zero flag + jr z, __POPOUT + ex af, af' ; Saves Zero flag + ld (hl), a + inc hl + ex af, af' ; Recovers Zero Flag + jp __POPOUT __CHR_END: - ld hl, (TMP) - push hl ; Restores return addr - ex de, hl ; Recovers original HL ptr - ret - ENDP + ld hl, (TMP) + push hl ; Restores return addr + ex de, hl ; Recovers original HL ptr + ret + ENDP + pop namespace #line 32 "arden2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -477,94 +485,96 @@ __CHR_END: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 33 "arden2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -573,138 +583,144 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 34 "arden2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 35 "arden2.bas" END diff --git a/tests/functional/arr_addr_global.asm b/tests/functional/arr_addr_global.asm index 425c7e01b..6225d40f7 100644 --- a/tests/functional/arr_addr_global.asm +++ b/tests/functional/arr_addr_global.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _aglobal: DEFW __LABEL0 _aglobal.__DATA__.__PTR__: @@ -36,8 +36,8 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _aglobal.__DATA__ ld de, 4 add hl, de @@ -48,9 +48,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arr_addr_local.asm b/tests/functional/arr_addr_local.asm index 56081732c..fdb2d437a 100644 --- a/tests/functional/arr_addr_local.asm +++ b/tests/functional/arr_addr_local.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 9 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld hl, 1 push hl ld hl, 1 @@ -61,7 +61,7 @@ _test: pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY push hl ld a, 99 pop hl @@ -71,7 +71,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -95,81 +95,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -177,16 +180,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -205,7 +208,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 55 "arr_addr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -282,6 +286,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -311,6 +316,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -376,9 +382,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -386,37 +393,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -429,90 +437,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -526,25 +536,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -559,6 +571,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -608,7 +621,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 56 "arr_addr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -678,94 +692,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 57 "arr_addr_local.bas" __LABEL0: DEFB 01h diff --git a/tests/functional/arr_addr_param.asm b/tests/functional/arr_addr_param.asm index 3b87f8b03..1bf575636 100644 --- a/tests/functional/arr_addr_param.asm +++ b/tests/functional/arr_addr_param.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _aglobal1: DEFW __LABEL0 _aglobal1.__DATA__.__PTR__: @@ -36,17 +36,17 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _aglobal1 push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -67,7 +67,7 @@ _test: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR push hl ld a, 99 pop hl @@ -98,81 +98,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -180,16 +183,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -208,6 +211,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 45 "arr_addr_param.bas" END diff --git a/tests/functional/array00.asm b/tests/functional/array00.asm index 1effe87d6..a43e4fca3 100644 --- a/tests/functional/array00.asm +++ b/tests/functional/array00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _bufferx: DEFW __LABEL0 _bufferx.__DATA__.__PTR__: @@ -57,14 +57,14 @@ __LABEL0: DEFW 0001h DEFW 0006h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/array01.asm b/tests/functional/array01.asm index 09666481d..d12979fd5 100644 --- a/tests/functional/array01.asm +++ b/tests/functional/array01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -37,16 +37,16 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld (_a.__DATA__ + 1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/array02.asm b/tests/functional/array02.asm index 326210be4..281847ae4 100644 --- a/tests/functional/array02.asm +++ b/tests/functional/array02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _a: @@ -39,16 +39,16 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld (_a.__DATA__ + 1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/array03.asm b/tests/functional/array03.asm index fc467f90c..a775216ac 100644 --- a/tests/functional/array03.asm +++ b/tests/functional/array03.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _a: @@ -39,22 +39,22 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld l, a ld h, 0 push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld a, (_b) ld (hl), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -81,81 +81,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -163,16 +166,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -191,6 +194,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 25 "array03.bas" END diff --git a/tests/functional/array04.asm b/tests/functional/array04.asm index 8f400e429..725bd3d03 100644 --- a/tests/functional/array04.asm +++ b/tests/functional/array04.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -48,16 +48,16 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 5 ld (_a.__DATA__ + 2), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/array05.asm b/tests/functional/array05.asm index 3095748e6..77b2489ac 100644 --- a/tests/functional/array05.asm +++ b/tests/functional/array05.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -50,16 +50,16 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) ld (_a.__DATA__ + 2), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/array06.asm b/tests/functional/array06.asm index 1e175fc45..0f273ad2e 100644 --- a/tests/functional/array06.asm +++ b/tests/functional/array06.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -50,12 +50,12 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, (_b) ld (hl), e inc hl @@ -63,9 +63,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -92,81 +92,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -174,16 +177,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -202,6 +205,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 25 "array06.bas" END diff --git a/tests/functional/array07.asm b/tests/functional/array07.asm index 7e7fb4071..a2f9e8e20 100644 --- a/tests/functional/array07.asm +++ b/tests/functional/array07.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -55,14 +55,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -81,15 +81,15 @@ _test: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY pop de - call __STORE_STR + call core.__STORE_STR _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -117,81 +117,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -199,16 +202,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -227,7 +230,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 45 "array07.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -353,9 +357,10 @@ TMP_ARR_PTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -363,37 +368,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -403,94 +409,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 46 "array07.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -567,6 +575,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -596,6 +605,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -668,90 +678,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -773,132 +785,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -923,5 +940,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 47 "array07.bas" END diff --git a/tests/functional/array08.asm b/tests/functional/array08.asm index cd0f232cd..51eb71afe 100644 --- a/tests/functional/array08.asm +++ b/tests/functional/array08.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _s: @@ -57,20 +57,20 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, (_s) - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -97,81 +97,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -179,16 +182,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -207,7 +210,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 23 "array08.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -284,6 +288,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -313,6 +318,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -438,9 +444,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -448,37 +455,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -491,90 +499,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -644,94 +654,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -753,132 +765,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -903,5 +920,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 24 "array08.bas" END diff --git a/tests/functional/array09.asm b/tests/functional/array09.asm index 0382ab24f..3ed39794a 100644 --- a/tests/functional/array09.asm +++ b/tests/functional/array09.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -57,20 +57,20 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, (_c) - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -97,81 +97,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -179,16 +182,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -207,7 +210,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 23 "array09.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -284,6 +288,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -313,6 +318,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -438,9 +444,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -448,37 +455,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -491,90 +499,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -644,94 +654,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -753,132 +765,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -903,5 +920,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 24 "array09.bas" END diff --git a/tests/functional/array10.asm b/tests/functional/array10.asm index 2a0120e0b..eab598586 100644 --- a/tests/functional/array10.asm +++ b/tests/functional/array10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _tn: DEFB 00 _rn: @@ -140,8 +140,8 @@ __LABEL1: DEFW 0001h DEFW 0005h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 4 push hl ld a, (_tn) @@ -149,7 +149,7 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _x - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) @@ -164,7 +164,7 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _x - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) @@ -178,7 +178,7 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _x - call __ARRAY + call core.__ARRAY pop de ld (hl), e inc hl @@ -186,9 +186,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -215,81 +215,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -297,16 +300,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -325,6 +328,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 58 "array10.bas" END diff --git a/tests/functional/array12.asm b/tests/functional/array12.asm index 41b923205..f71934e33 100644 --- a/tests/functional/array12.asm +++ b/tests/functional/array12.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _s: @@ -278,22 +278,22 @@ __LABEL0: DEFW 0001h DEFW 000Bh DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, (_s) - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -320,81 +320,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -402,16 +405,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -430,7 +433,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 25 "array12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -507,6 +511,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -536,6 +541,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -661,9 +667,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -671,37 +678,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -714,90 +722,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -867,94 +877,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -976,132 +988,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1126,5 +1143,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 26 "array12.bas" END diff --git a/tests/functional/array_check_param.asm b/tests/functional/array_check_param.asm index 094f25d4a..160c8be2d 100644 --- a/tests/functional/array_check_param.asm +++ b/tests/functional/array_check_param.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,15 +52,15 @@ _pickString: pop hl ld de, -5 add hl, de - call __PLOADF - call __FTOU32REG + call core.__PLOADF + call core.__FTOU32REG push hl push ix pop hl ld de, 4 add hl, de - call __ARRAY_PTR - call __ILOADSTR + call core.__ARRAY_PTR + call core.__ILOADSTR _pickString__leave: ld sp, ix pop ix @@ -87,81 +87,84 @@ _pickString__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -169,16 +172,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -197,81 +200,85 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 47 "array_check_param.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -288,11 +295,12 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 48 "array_check_param.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -358,6 +366,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -387,6 +396,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -452,9 +462,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -462,37 +473,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -505,125 +517,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 49 "array_check_param.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -635,6 +651,7 @@ __LOADSTR: ; __FASTCALL__ entry ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -645,21 +662,24 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 50 "array_check_param.bas" END diff --git a/tests/functional/array_check_warn.asm b/tests/functional/array_check_warn.asm index 2ac66bcfd..43877fefb 100644 --- a/tests/functional/array_check_warn.asm +++ b/tests/functional/array_check_warn.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00 _aux: @@ -43,8 +43,8 @@ _aux1.__DATA__: __LABEL1: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_aux.__DATA__ + 4) ld (_c), a ld a, (_aux1.__DATA__ + -1) @@ -53,9 +53,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arraycopy0.asm b/tests/functional/arraycopy0.asm index e3695c7df..a268c7030 100644 --- a/tests/functional/arraycopy0.asm +++ b/tests/functional/arraycopy0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _grid: @@ -46,8 +46,8 @@ _gridcopy.__DATA__: __LABEL1: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 5 ld b, h ld c, l @@ -65,9 +65,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arraycopy1.asm b/tests/functional/arraycopy1.asm index 8f0eb0ccb..5cdb60490 100644 --- a/tests/functional/arraycopy1.asm +++ b/tests/functional/arraycopy1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _grid: DEFW __LABEL1 _grid.__DATA__.__PTR__: @@ -36,14 +36,14 @@ _grid.__DATA__: __LABEL1: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -62,7 +62,7 @@ _Test: ld hl, -4 ld de, __LABEL0 ld bc, 5 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) push hl @@ -77,7 +77,7 @@ _Test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -159,6 +159,7 @@ _Test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -188,6 +189,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -253,9 +255,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -263,37 +266,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -306,90 +310,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -403,25 +409,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -436,6 +444,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -485,7 +494,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 48 "arraycopy1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -555,94 +565,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 49 "arraycopy1.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arraycopy2.asm b/tests/functional/arraycopy2.asm index a7a9124ac..2f98a87ec 100644 --- a/tests/functional/arraycopy2.asm +++ b/tests/functional/arraycopy2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _gridcopy: DEFW __LABEL2 _gridcopy.__DATA__.__PTR__: @@ -36,14 +36,14 @@ _gridcopy.__DATA__: __LABEL2: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,7 +64,7 @@ _Test: ld hl, -4 ld de, __LABEL0 ld bc, 5 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) push hl @@ -79,7 +79,7 @@ _Test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -161,6 +161,7 @@ _Test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -190,6 +191,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -255,9 +257,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -265,37 +268,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -308,90 +312,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -405,25 +411,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -438,6 +446,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -487,7 +496,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 50 "arraycopy2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -557,94 +567,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 51 "arraycopy2.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arraycopy3.asm b/tests/functional/arraycopy3.asm index a29727051..09122344b 100644 --- a/tests/functional/arraycopy3.asm +++ b/tests/functional/arraycopy3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,11 +57,11 @@ _Test: ld hl, -4 ld de, __LABEL0 ld bc, 5 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld hl, -8 ld de, __LABEL2 ld bc, 5 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-6) ld h, (ix-5) push hl @@ -79,10 +79,10 @@ _Test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -164,6 +164,7 @@ _Test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -193,6 +194,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -258,9 +260,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -268,37 +271,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -311,90 +315,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -408,25 +414,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -441,6 +449,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -490,7 +499,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 66 "arraycopy3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -560,94 +570,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 67 "arraycopy3.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arraycopy4.asm b/tests/functional/arraycopy4.asm index a1cf7701d..242e81264 100644 --- a/tests/functional/arraycopy4.asm +++ b/tests/functional/arraycopy4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,11 +56,11 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 22 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld hl, -8 ld de, __LABEL1 ld bc, 22 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-6) ld h, (ix-5) push hl @@ -69,7 +69,7 @@ _test: push hl ld hl, 11 push hl - call STR_ARRAYCOPY + call core.STR_ARRAYCOPY _test__leave: ex af, af' exx @@ -77,12 +77,12 @@ _test__leave: push hl ld l, (ix-2) ld h, (ix-1) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ld hl, 11 push hl ld l, (ix-6) ld h, (ix-5) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -164,6 +164,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -193,6 +194,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -258,9 +260,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -268,37 +271,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -311,90 +315,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -408,25 +414,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -441,6 +449,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -490,7 +499,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 66 "arraycopy4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -564,134 +574,138 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 67 "arraycopy4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strarraycpy.asm" ; (K)opyleft - by Jose M. Rodriguez de la Rosa (a.k.a. Boriel) @@ -706,14 +720,16 @@ __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself ; Modifies C register ; There is a routine similar to this one ; at ROM address L2AEE + push namespace core __LOAD_DE_DE: - ex de, hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c - ex de, hl - ret + ex de, hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c + ex de, hl + ret + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/strarraycpy.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" @@ -796,132 +812,137 @@ __LOAD_DE_DE: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/strarraycpy.asm" + push namespace core STR_ARRAYCOPY: ; Copies an array of string a$ = b$ ; Parameters in the stack: @@ -965,6 +986,7 @@ LOOP: inc de jp LOOP ENDP + pop namespace #line 68 "arraycopy4.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arrbase1.asm b/tests/functional/arrbase1.asm index 2d940f951..b046f0256 100644 --- a/tests/functional/arrbase1.asm +++ b/tests/functional/arrbase1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _k: DEFB 00, 00 _c: @@ -40,14 +40,14 @@ __LABEL5: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 1 ld (_k), hl jp __LABEL0 __LABEL3: ld a, 2 - call __READ + call core.__READ push af ld hl, 0 push hl @@ -55,7 +55,7 @@ __LABEL3: dec hl push hl ld hl, _c - call __ARRAY + call core.__ARRAY pop af ld (hl), a __LABEL4: @@ -72,9 +72,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -104,81 +104,84 @@ __DATA__END: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -186,16 +189,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -214,7 +217,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 47 "arrbase1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -237,6 +241,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -266,6 +271,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -392,9 +398,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -402,37 +409,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -445,148 +453,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -597,91 +612,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -698,124 +717,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -823,18 +848,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -904,94 +930,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -1003,6 +1031,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1279,5 +1308,6 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 48 "arrbase1.bas" END diff --git a/tests/functional/arrcheck.asm b/tests/functional/arrcheck.asm index 302cfc2dd..780982215 100644 --- a/tests/functional/arrcheck.asm +++ b/tests/functional/arrcheck.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00 _b: @@ -98,8 +98,8 @@ __LABEL0: DEFW 0001h DEFW 0006h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, 5 @@ -109,7 +109,7 @@ __MAIN_PROGRAM__: ld hl, 10 push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld (hl), 7 ld hl, (_b) push hl @@ -122,16 +122,16 @@ __MAIN_PROGRAM__: ld hl, 10 push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld a, (hl) ld (_c), a ld (_c), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -158,33 +158,36 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -214,65 +217,67 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: pop de -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack ex de, hl or a sbc hl, bc ld a, ERROR_SubscriptWrong jp c, __ERROR ex de, hl -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -280,16 +285,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -308,6 +313,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 43 "arrcheck.bas" END diff --git a/tests/functional/arrconst.asm b/tests/functional/arrconst.asm index 2f8b3f080..b368e9de3 100644 --- a/tests/functional/arrconst.asm +++ b/tests/functional/arrconst.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _p: DEFW (_a.__DATA__ + 0) _a: @@ -47,15 +47,15 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_p) ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels.asm b/tests/functional/arrlabels.asm index c337a928a..3ffe374a6 100644 --- a/tests/functional/arrlabels.asm +++ b/tests/functional/arrlabels.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -29,8 +29,8 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__label1: __LABEL__label2: __LABEL__label3: @@ -42,9 +42,9 @@ __LABEL__label3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels1.asm b/tests/functional/arrlabels1.asm index 70e2c45a8..8b905784a 100644 --- a/tests/functional/arrlabels1.asm +++ b/tests/functional/arrlabels1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -29,14 +29,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels10a.asm b/tests/functional/arrlabels10a.asm index 35159d6dd..9113d7edc 100644 --- a/tests/functional/arrlabels10a.asm +++ b/tests/functional/arrlabels10a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -29,14 +29,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels10b.asm b/tests/functional/arrlabels10b.asm index e0bbecadc..cf164b6b6 100644 --- a/tests/functional/arrlabels10b.asm +++ b/tests/functional/arrlabels10b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -34,14 +34,14 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 04h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels2.asm b/tests/functional/arrlabels2.asm index aded99bf7..c9714a1a6 100644 --- a/tests/functional/arrlabels2.asm +++ b/tests/functional/arrlabels2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -29,8 +29,8 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a.__DATA__ + 0) push hl ld a, 5 @@ -39,9 +39,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels3.asm b/tests/functional/arrlabels3.asm index 23c1a9b5a..4f5277d58 100644 --- a/tests/functional/arrlabels3.asm +++ b/tests/functional/arrlabels3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -29,8 +29,8 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a.__DATA__ + 0) push hl ld a, 5 @@ -39,9 +39,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels4.asm b/tests/functional/arrlabels4.asm index b4f8da048..1d1ba991f 100644 --- a/tests/functional/arrlabels4.asm +++ b/tests/functional/arrlabels4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__label1: __LABEL__label2: __LABEL__label3: @@ -32,9 +32,9 @@ __LABEL__label3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,7 +55,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) ld a, (hl) @@ -71,7 +71,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -153,6 +153,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -182,6 +183,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -247,9 +249,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -257,37 +260,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -300,90 +304,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -397,25 +403,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -430,6 +438,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -479,7 +488,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 55 "arrlabels4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -549,94 +559,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 56 "arrlabels4.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arrlabels5.asm b/tests/functional/arrlabels5.asm index 4e0fac4a0..926fb7ea2 100644 --- a/tests/functional/arrlabels5.asm +++ b/tests/functional/arrlabels5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY __LABEL__label1: __LABEL__label2: __LABEL__label3: @@ -71,7 +71,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -153,6 +153,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -182,6 +183,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -247,9 +249,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -257,37 +260,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -300,90 +304,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -397,25 +403,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -430,6 +438,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -479,7 +488,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 55 "arrlabels5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -549,94 +559,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 56 "arrlabels5.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arrlabels6.asm b/tests/functional/arrlabels6.asm index b63c3d2ad..34a1a8ec4 100644 --- a/tests/functional/arrlabels6.asm +++ b/tests/functional/arrlabels6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -29,8 +29,8 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a.__DATA__ + 0) push hl ld a, 5 @@ -42,9 +42,9 @@ __LABEL__label3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/arrlabels7.asm b/tests/functional/arrlabels7.asm index 2f93f9ebf..b770d2cb1 100644 --- a/tests/functional/arrlabels7.asm +++ b/tests/functional/arrlabels7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) ld a, (hl) @@ -71,7 +71,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -153,6 +153,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -182,6 +183,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -247,9 +249,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -257,37 +260,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -300,90 +304,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -397,25 +403,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -430,6 +438,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -479,7 +488,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 55 "arrlabels7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -549,94 +559,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 56 "arrlabels7.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arrlabels8.asm b/tests/functional/arrlabels8.asm index 55965a1b3..e2428b9fc 100644 --- a/tests/functional/arrlabels8.asm +++ b/tests/functional/arrlabels8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__label1: __LABEL__label2: __LABEL__label3: @@ -32,9 +32,9 @@ __LABEL__label3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,7 +55,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) ld a, (hl) @@ -71,7 +71,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -153,6 +153,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -182,6 +183,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -247,9 +249,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -257,37 +260,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -300,90 +304,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -397,25 +403,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -430,6 +438,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -479,7 +488,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 55 "arrlabels8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -549,94 +559,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 56 "arrlabels8.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/arrlabels9.asm b/tests/functional/arrlabels9.asm index f707c112c..9c72cf402 100644 --- a/tests/functional/arrlabels9.asm +++ b/tests/functional/arrlabels9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__label1: __LABEL__label2: __LABEL__label3: @@ -32,9 +32,9 @@ __LABEL__label3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,7 +55,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) ld a, (hl) @@ -71,7 +71,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -153,6 +153,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -182,6 +183,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -247,9 +249,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -257,37 +260,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -300,90 +304,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -397,25 +403,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -430,6 +438,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -479,7 +488,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 55 "arrlabels9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -549,94 +559,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 56 "arrlabels9.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/asm_error_line.asm b/tests/functional/asm_error_line.asm index 80db54fc6..826ce203b 100644 --- a/tests/functional/asm_error_line.asm +++ b/tests/functional/asm_error_line.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 3 "asm_error_line.bas" test: dk 10, 20 #line 5 "asm_error_line.bas" @@ -29,9 +29,9 @@ test: dk 10, 20 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/asm_tokens.asm b/tests/functional/asm_tokens.asm index 7eb2928b2..1e678d35d 100644 --- a/tests/functional/asm_tokens.asm +++ b/tests/functional/asm_tokens.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "asm_tokens.bas" ld a, {{macro_value}} #line 4 "asm_tokens.bas" ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/astore16.asm b/tests/functional/astore16.asm index 369545d61..3e5223118 100644 --- a/tests/functional/astore16.asm +++ b/tests/functional/astore16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,17 +8,17 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 _obj: @@ -61,8 +61,8 @@ _obj.__DATA__: __LABEL5: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_i), a jp __LABEL0 @@ -72,7 +72,7 @@ __LABEL3: ld h, 0 push hl ld hl, _obj - call __ARRAY + call core.__ARRAY ld (hl), 15 inc hl ld (hl), 39 @@ -81,13 +81,13 @@ __LABEL3: ld h, 0 push hl ld hl, _obj - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) ex de, hl - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL __LABEL4: ld hl, _i inc (hl) @@ -100,9 +100,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -129,81 +129,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -211,16 +214,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -239,7 +242,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 51 "astore16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -248,70 +252,75 @@ TMP_ARR_PTR: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -341,49 +350,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -391,319 +406,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -758,469 +793,477 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 52 "astore16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1243,76 +1286,79 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 53 "astore16.bas" END diff --git a/tests/functional/ataddr.asm b/tests/functional/ataddr.asm index 15496645f..2d507728d 100644 --- a/tests/functional/ataddr.asm +++ b/tests/functional/ataddr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -634,8 +634,8 @@ __LABEL0: DEFW 0001h DEFW 000Bh DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a.__DATA__ ld de, 295 add hl, de @@ -643,9 +643,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/atfunc0.asm b/tests/functional/atfunc0.asm index fd833a047..f47138f37 100644 --- a/tests/functional/atfunc0.asm +++ b/tests/functional/atfunc0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _myfunc ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/atfunc1.asm b/tests/functional/atfunc1.asm index fd833a047..f47138f37 100644 --- a/tests/functional/atfunc1.asm +++ b/tests/functional/atfunc1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _myfunc ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/atlabel.asm b/tests/functional/atlabel.asm index c08a2262f..0231c0158 100644 --- a/tests/functional/atlabel.asm +++ b/tests/functional/atlabel.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _radians: _a: DEFB 82h @@ -25,14 +25,14 @@ _a: DEFB 0Fh DEFB 0DAh DEFB 0A2h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/atlabel1.asm b/tests/functional/atlabel1.asm index 126431c7f..6fb98222a 100644 --- a/tests/functional/atlabel1.asm +++ b/tests/functional/atlabel1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__mylabel: _radians: ld a, 082h ld de, 00000h ld bc, 00000h ld hl, _radians - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -43,30 +43,32 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 24 "atlabel1.bas" END diff --git a/tests/functional/atlabel2.asm b/tests/functional/atlabel2.asm index 856d8a023..14036a7d4 100644 --- a/tests/functional/atlabel2.asm +++ b/tests/functional/atlabel2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__b: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/atlabel3.asm b/tests/functional/atlabel3.asm index fdc5d4cd6..3a289b36e 100644 --- a/tests/functional/atlabel3.asm +++ b/tests/functional/atlabel3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ato3.asm b/tests/functional/ato3.asm index 6b3144e7d..80224ba4d 100644 --- a/tests/functional/ato3.asm +++ b/tests/functional/ato3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _d1: @@ -34,8 +34,8 @@ _VOFFS128K: DEFB 00 _VOFFSPEN: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_VOFFS48K) ld hl, (_b - 1) sub h @@ -57,9 +57,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/attr.asm b/tests/functional/attr.asm index 7b6777456..467c50ce4 100644 --- a/tests/functional/attr.asm +++ b/tests/functional/attr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a - call INK + call core.INK ld a, 7 - call PAPER + call core.PAPER ld a, 1 - call FLASH + call core.FLASH ld a, 1 - call OVER + call core.OVER ld a, 1 - call BOLD - call COPY_ATTR + call core.BOLD + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,6 +53,7 @@ __END_PROGRAM: #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -60,200 +61,213 @@ __END_PROGRAM: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 28 "attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 30 "attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 31 "attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 32 "attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 33 "attr.bas" END diff --git a/tests/functional/attr_in_subs.asm b/tests/functional/attr_in_subs.asm index 21fdae7e8..2200c66f4 100644 --- a/tests/functional/attr_in_subs.asm +++ b/tests/functional/attr_in_subs.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _screenAttributes2 - call CLS + call core.CLS ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -41,12 +41,12 @@ _screenAttributes2: ld ix, 0 add ix, sp ld a, 4 - call PAPER + call core.PAPER ld a, 1 - call BRIGHT + call core.BRIGHT ld a, 2 - call INK - call COPY_ATTR + call core.INK + call core.COPY_ATTR _screenAttributes2__leave: ld sp, ix pop ix @@ -57,6 +57,7 @@ _screenAttributes2__leave: ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -64,38 +65,41 @@ _screenAttributes2__leave: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 34 "attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS @@ -104,161 +108,171 @@ BRIGHT_TMP: ; Our faster implementation #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 35 "attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 36 "attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 37 "attr_in_subs.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 38 "attr_in_subs.bas" END diff --git a/tests/functional/bad_pragma.asm b/tests/functional/bad_pragma.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/bad_pragma.asm +++ b/tests/functional/bad_pragma.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/band16.asm b/tests/functional/band16.asm index ecfd9e9f7..4b5ec825a 100644 --- a/tests/functional/band16.asm +++ b/tests/functional/band16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld hl, 0 ld a, l ld (_b), a ld de, 1 ld hl, (_a) - call __BAND16 + call core.__BAND16 ld a, l ld (_b), a pop hl @@ -42,7 +42,7 @@ __MAIN_PROGRAM__: ld (_b), a ld de, 1 ld hl, (_a) - call __BAND16 + call core.__BAND16 ld a, l ld (_b), a pop hl @@ -50,15 +50,15 @@ __MAIN_PROGRAM__: ld (_b), a ld de, (_a) ld hl, (_a) - call __BAND16 + call core.__BAND16 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,13 +76,15 @@ __END_PROGRAM: ; Performs 16bit or 16bit and returns the boolean ; Input: HL, DE ; Output: HL <- HL AND DE + push namespace core __BAND16: - ld a, h - and d + ld a, h + and d ld h, a ld a, l and e ld l, a ret + pop namespace #line 46 "band16.bas" END diff --git a/tests/functional/band32.asm b/tests/functional/band32.asm index fe4cf0e3d..a48502067 100644 --- a/tests/functional/band32.asm +++ b/tests/functional/band32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 0 - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -39,7 +39,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 65535 - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, (_a) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, (_a) @@ -66,7 +66,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, (_a) @@ -75,7 +75,7 @@ __MAIN_PROGRAM__: push bc ld bc, 65535 push bc - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -84,15 +84,15 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __BAND32 + call core.__BAND32 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -107,18 +107,19 @@ __END_PROGRAM: ; Performs 32bit and 32bit and returns the bitwise ; result in DE,HL ; First operand in DE,HL 2nd operand into the stack + push namespace core __BAND32: ld b, h ld c, l ; BC <- HL pop hl ; Return address ex (sp), hl ; HL <- Lower part of 2nd Operand - ld a, b + ld a, b and h ld b, a ld a, c and l ld c, a ; BC <- BC & HL - pop hl ; Return dddress + pop hl ; Return dddress ex (sp), hl ; HL <- High part of 2nd Operand ld a, d and h @@ -129,5 +130,6 @@ __BAND32: ld h, b ld l, c ; HL <- BC ; Always return DE,HL pair regs ret + pop namespace #line 80 "band32.bas" END diff --git a/tests/functional/band8.asm b/tests/functional/band8.asm index 89d38f3ff..82a549c52 100644 --- a/tests/functional/band8.asm +++ b/tests/functional/band8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) xor a ld (_b), a @@ -54,9 +54,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bin00.asm b/tests/functional/bin00.asm index 8e5014b95..75ae27762 100644 --- a/tests/functional/bin00.asm +++ b/tests/functional/bin00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00 _d: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 41 ld (_c), a ld hl, 2047 @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bin01.asm b/tests/functional/bin01.asm index 3fc005cd9..96b6e435c 100644 --- a/tests/functional/bin01.asm +++ b/tests/functional/bin01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bin03.asm b/tests/functional/bin03.asm index 017c367e8..12665057b 100644 --- a/tests/functional/bin03.asm +++ b/tests/functional/bin03.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_a), a inc a @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bitwise.asm b/tests/functional/bitwise.asm index c9e4df1e0..15578168e 100644 --- a/tests/functional/bitwise.asm +++ b/tests/functional/bitwise.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_a), a cpl @@ -39,9 +39,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bnot16.asm b/tests/functional/bnot16.asm index 93331cc93..55bcad4b0 100644 --- a/tests/functional/bnot16.asm +++ b/tests/functional/bnot16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 255 ld (_b), a ld hl, 65535 @@ -32,15 +32,15 @@ __MAIN_PROGRAM__: ld (_b), a ld hl, 65534 ld (_a), hl - call __BNOT16 + call core.__BNOT16 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -58,13 +58,15 @@ __END_PROGRAM: ; Performs 16bit NEGATION ; Input: HL ; Output: HL <- NOT HL + push namespace core __BNOT16: - ld a, h + ld a, h cpl ld h, a ld a, l cpl ld l, a ret + pop namespace #line 28 "bnot16.bas" END diff --git a/tests/functional/bnot32.asm b/tests/functional/bnot32.asm index 28f8e9508..316c16709 100644 --- a/tests/functional/bnot32.asm +++ b/tests/functional/bnot32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) - call __BNOT32 + call core.__BNOT32 ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,19 +50,21 @@ __END_PROGRAM: ; Performs 32bit NEGATION (cpl) ; Input: DE,HL ; Output: DE,HL <- NOT DE,HL + push namespace core __BNOT32: - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a ret + pop namespace #line 22 "bnot32.bas" END diff --git a/tests/functional/bor16.asm b/tests/functional/bor16.asm index 6f7dc1801..a3d9e9f41 100644 --- a/tests/functional/bor16.asm +++ b/tests/functional/bor16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld a, l ld (_b), a ld de, 1 ld hl, (_a) - call __BOR16 + call core.__BOR16 ld a, l ld (_b), a ld hl, (_a) @@ -41,7 +41,7 @@ __MAIN_PROGRAM__: ld (_b), a ld de, 1 ld hl, (_a) - call __BOR16 + call core.__BOR16 ld a, l ld (_b), a ld hl, (_a) @@ -50,15 +50,15 @@ __MAIN_PROGRAM__: ld (_b), a ld de, (_a) ld hl, (_a) - call __BOR16 + call core.__BOR16 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,13 +76,15 @@ __END_PROGRAM: ; Performs 16bit or 16bit and returns the boolean ; Input: HL, DE ; Output: HL <- HL OR DE + push namespace core __BOR16: - ld a, h - or d + ld a, h + or d ld h, a ld a, l or e ld l, a ret + pop namespace #line 46 "bor16.bas" END diff --git a/tests/functional/bor32.asm b/tests/functional/bor32.asm index 12c052342..09bdcc6a9 100644 --- a/tests/functional/bor32.asm +++ b/tests/functional/bor32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 0 - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -39,7 +39,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 65535 - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, (_a) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, (_a) @@ -66,7 +66,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, (_a) @@ -75,7 +75,7 @@ __MAIN_PROGRAM__: push bc ld bc, 65535 push bc - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -84,15 +84,15 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __BOR32 + call core.__BOR32 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -107,18 +107,19 @@ __END_PROGRAM: ; Performs 32bit or 32bit and returns the bitwise ; result DE,HL ; First operand in DE,HL 2nd operand into the stack + push namespace core __BOR32: ld b, h ld c, l ; BC <- HL pop hl ; Return address ex (sp), hl ; HL <- Lower part of 2nd Operand - ld a, b + ld a, b or h ld b, a ld a, c or l ld c, a ; BC <- BC & HL - pop hl ; Return dddress + pop hl ; Return dddress ex (sp), hl ; HL <- High part of 2nd Operand ld a, d or h @@ -129,5 +130,6 @@ __BOR32: ld h, b ld l, c ; HL <- BC ; Always return DE,HL pair regs ret + pop namespace #line 80 "bor32.bas" END diff --git a/tests/functional/bor8.asm b/tests/functional/bor8.asm index 4a25acc8e..565718114 100644 --- a/tests/functional/bor8.asm +++ b/tests/functional/bor8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -48,9 +48,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bound00.asm b/tests/functional/bound00.asm index 43efbc2fb..1ce749022 100644 --- a/tests/functional/bound00.asm +++ b/tests/functional/bound00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -44,8 +44,8 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 1 ld (_b), hl ld hl, 1 @@ -53,9 +53,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bound01.asm b/tests/functional/bound01.asm index f4898c0b8..ef16617f8 100644 --- a/tests/functional/bound01.asm +++ b/tests/functional/bound01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -87,8 +87,8 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 8 ld (_b), hl ld hl, 2 @@ -100,9 +100,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bound02.asm b/tests/functional/bound02.asm index 12f79f760..9fb1f5005 100644 --- a/tests/functional/bound02.asm +++ b/tests/functional/bound02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _c: @@ -92,15 +92,15 @@ __LABEL0: _a.__LBOUND__: DEFW 0002h DEFW 0003h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_b), a ld l, a ld h, 0 push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld a, (_b) inc a @@ -108,7 +108,7 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld a, (_b) dec a @@ -116,14 +116,14 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -145,6 +145,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -205,5 +206,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 41 "bound02.bas" END diff --git a/tests/functional/bound03.asm b/tests/functional/bound03.asm index c1611f8a8..1d8eb9c0d 100644 --- a/tests/functional/bound03.asm +++ b/tests/functional/bound03.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _c: @@ -92,15 +92,15 @@ __LABEL0: _a.__UBOUND__: DEFW 0008h DEFW 0006h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_b), a ld l, a ld h, 0 push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld a, (_b) inc a @@ -108,7 +108,7 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld a, (_b) dec a @@ -116,14 +116,14 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -145,6 +145,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -205,5 +206,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 41 "bound03.bas" END diff --git a/tests/functional/bound04.asm b/tests/functional/bound04.asm index a9167cdac..07e446609 100644 --- a/tests/functional/bound04.asm +++ b/tests/functional/bound04.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a: @@ -71,8 +71,8 @@ __LABEL0: DEFW 0001h DEFW 0007h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 ld (_c), hl ld hl, 2 @@ -80,9 +80,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/break.asm b/tests/functional/break.asm index 49047b91d..17d54b875 100644 --- a/tests/functional/break.asm +++ b/tests/functional/break.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: push hl ld hl, 4 - call CHECK_BREAK + call core.CHECK_BREAK __LABEL__20: ld a, 1 ld (_a), a push hl ld hl, 5 - call CHECK_BREAK + call core.CHECK_BREAK __LABEL__30: ld a, 2 ld (_a), a @@ -39,18 +39,18 @@ __LABEL__30: ld (_a), a push hl ld hl, 6 - call CHECK_BREAK + call core.CHECK_BREAK ld a, 40 ld (_a), a push hl ld hl, 10 - call CHECK_BREAK + call core.CHECK_BREAK ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,6 +64,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -93,11 +94,13 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/break.asm" ; Check if BREAK is pressed ; Return if not. Else Raises ; L BREAK Into Program Error ; HL contains the line number we want to appear in the error msg. + push namespace core CHECK_BREAK: PROC LOCAL PPC, TS_BRK, NO_BREAK @@ -115,5 +118,6 @@ NO_BREAK: PPC EQU 23621 TS_BRK EQU 8020 ENDP + pop namespace #line 40 "break.bas" END diff --git a/tests/functional/britlion0.asm b/tests/functional/britlion0.asm index 36ffbb7e1..646b9f4b9 100644 --- a/tests/functional/britlion0.asm +++ b/tests/functional/britlion0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _num: DEFB 00, 00, 00, 00 _dif: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_num) ld de, (_num + 2) ld a, e @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/bxor16.asm b/tests/functional/bxor16.asm index 3a6754bd6..591c08823 100644 --- a/tests/functional/bxor16.asm +++ b/tests/functional/bxor16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld a, l ld (_b), a ld de, 1 ld hl, (_a) - call __BXOR16 + call core.__BXOR16 ld a, l ld (_b), a ld hl, (_a) - call __NEGHL + call core.__NEGHL ld a, l ld (_b), a ld hl, (_a) @@ -41,24 +41,24 @@ __MAIN_PROGRAM__: ld (_b), a ld de, 1 ld hl, (_a) - call __BXOR16 + call core.__BXOR16 ld a, l ld (_b), a ld hl, (_a) - call __NEGHL + call core.__NEGHL ld a, l ld (_b), a ld de, (_a) ld hl, (_a) - call __BXOR16 + call core.__BXOR16 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,28 +76,32 @@ __END_PROGRAM: ; Performs 16bit xor 16bit and returns the boolean ; Input: HL, DE ; Output: HL <- HL XOR DE + push namespace core __BXOR16: - ld a, h - xor d + ld a, h + xor d ld h, a ld a, l xor e ld l, a ret + pop namespace #line 46 "bxor16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 47 "bxor16.bas" END diff --git a/tests/functional/bxor32.asm b/tests/functional/bxor32.asm index 7c8f8c018..108bfc7c2 100644 --- a/tests/functional/bxor32.asm +++ b/tests/functional/bxor32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 0 - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -39,7 +39,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 65535 - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, (_a) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, (_a) @@ -66,7 +66,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, (_a) @@ -75,7 +75,7 @@ __MAIN_PROGRAM__: push bc ld bc, 65535 push bc - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, (_a + 2) @@ -84,15 +84,15 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __BXOR32 + call core.__BXOR32 ld a, l ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -107,18 +107,19 @@ __END_PROGRAM: ; Performs 32bit xor 32bit and returns the bitwise ; result DE,HL ; First operand in DE,HL 2nd operand into the stack + push namespace core __BXOR32: ld b, h ld c, l ; BC <- HL pop hl ; Return address ex (sp), hl ; HL <- Lower part of 2nd Operand - ld a, b + ld a, b xor h ld b, a ld a, c xor l ld c, a ; BC <- BC & HL - pop hl ; Return dddress + pop hl ; Return dddress ex (sp), hl ; HL <- High part of 2nd Operand ld a, d xor h @@ -129,5 +130,6 @@ __BXOR32: ld h, b ld l, c ; HL <- BC ; Always return DE,HL pair regs ret + pop namespace #line 80 "bxor32.bas" END diff --git a/tests/functional/bxor8.asm b/tests/functional/bxor8.asm index e63f64f84..83f6c1ffd 100644 --- a/tests/functional/bxor8.asm +++ b/tests/functional/bxor8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -48,9 +48,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/byref16.asm b/tests/functional/byref16.asm index 2d1b3b4e2..011795eb6 100644 --- a/tests/functional/byref16.asm +++ b/tests/functional/byref16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,14 +44,14 @@ _test: push hl ld hl, 0 ld bc, 4 - call __PISTORE16 + call core.__PISTORE16 ld l, (ix-2) ld h, (ix-1) ld bc, 4 - call __PISTORE16 + call core.__PISTORE16 ld hl, (_y) ld bc, 4 - call __PISTORE16 + call core.__PISTORE16 ld h, (ix+5) ld l, (ix+4) ld c, (hl) @@ -69,19 +69,21 @@ _test__leave: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/istore16.asm" + push namespace core __PISTORE16: ; stores an integer in hl into address IX + BC; Destroys DE - ex de, hl - push ix - pop hl - add hl, bc + ex de, hl + push ix + pop hl + add hl, bc __ISTORE16: ; Load address at hl, and stores E,D integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ld (hl), e - inc hl - ld (hl), d - ret + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 48 "byref16.bas" END diff --git a/tests/functional/byref32.asm b/tests/functional/byref32.asm index 984c3bfbd..d8a9a25e2 100644 --- a/tests/functional/byref32.asm +++ b/tests/functional/byref32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,20 +46,20 @@ _test: ld de, 0 ld hl, 0 ld bc, 4 - call __PISTORE32 + call core.__PISTORE32 ld l, (ix-4) ld h, (ix-3) ld e, (ix-2) ld d, (ix-1) ld bc, 4 - call __PISTORE32 + call core.__PISTORE32 ld hl, (_y) ld de, (_y + 2) ld bc, 4 - call __PISTORE32 + call core.__PISTORE32 ld h, (ix+5) ld l, (ix+4) - call __ILOAD32 + call core.__ILOAD32 ld (_y), hl ld (_y + 2), de _test__leave: @@ -76,40 +76,44 @@ _test__leave: ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 51 "byref32.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pistore32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" + push namespace core __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/pistore32.asm" ; The content of this file has been moved to "store32.asm" #line 52 "byref32.bas" diff --git a/tests/functional/byrefbyref.asm b/tests/functional/byrefbyref.asm index 916111e3c..a6d2b055b 100644 --- a/tests/functional/byrefbyref.asm +++ b/tests/functional/byrefbyref.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _v push hl call _primero ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/byreff.asm b/tests/functional/byreff.asm index 49f56ed32..5d85ab204 100644 --- a/tests/functional/byreff.asm +++ b/tests/functional/byreff.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,28 +49,28 @@ _test: ld de, 00000h ld bc, 00000h ld hl, 4 - call __PISTOREF + call core.__PISTOREF push ix pop hl ld de, -5 add hl, de - call __PLOADF + call core.__PLOADF ld hl, 4 - call __PISTOREF + call core.__PISTOREF ld a, (_y) ld de, (_y + 1) ld bc, (_y + 3) ld hl, 4 - call __PISTOREF + call core.__PISTOREF push ix pop hl ld de, 4 add hl, de ld h, (ix+1) ld l, (ix+0) - call __ILOADF + call core.__ILOADF ld hl, _y - call __STOREF + call core.__STOREF _test__leave: ld sp, ix pop ix @@ -85,6 +85,7 @@ _test__leave: ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -95,53 +96,58 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 60 "byreff.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load ; A => Offset ; IX = Stack Frame ; RESULT: HL => IX + DE + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 61 "byreff.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 62 "byreff.bas" END diff --git a/tests/functional/byreff16.asm b/tests/functional/byreff16.asm index 048e52c3a..732262b7f 100644 --- a/tests/functional/byreff16.asm +++ b/tests/functional/byreff16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,20 +46,20 @@ _test: ld de, 0 ld hl, 0 ld bc, 4 - call __PISTORE32 + call core.__PISTORE32 ld l, (ix-4) ld h, (ix-3) ld e, (ix-2) ld d, (ix-1) ld bc, 4 - call __PISTORE32 + call core.__PISTORE32 ld hl, (_y) ld de, (_y + 2) ld bc, 4 - call __PISTORE32 + call core.__PISTORE32 ld h, (ix+5) ld l, (ix+4) - call __ILOAD32 + call core.__ILOAD32 ld (_y), hl ld (_y + 2), de _test__leave: @@ -76,40 +76,44 @@ _test__leave: ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 51 "byreff16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pistore32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" + push namespace core __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/pistore32.asm" ; The content of this file has been moved to "store32.asm" #line 52 "byreff16.bas" diff --git a/tests/functional/byrefstr.asm b/tests/functional/byrefstr.asm index 24453f965..496affcd3 100644 --- a/tests/functional/byrefstr.asm +++ b/tests/functional/byrefstr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,13 +49,13 @@ _test: push hl ld de, __LABEL0 ld bc, 4 - call __PISTORE_STR + call core.__PISTORE_STR ld l, (ix-2) ld h, (ix-1) ld d, h ld e, l ld bc, 4 - call __PISTORE_STR + call core.__PISTORE_STR ld h, (ix+5) ld l, (ix+4) ld c, (hl) @@ -65,14 +65,14 @@ _test: push hl ld de, __LABEL1 pop hl - call __ADDSTR + call core.__ADDSTR ld d, h ld e, l ld bc, 4 - call __PISTORE_STR2 + call core.__PISTORE_STR2 ld de, (_y) ld bc, 4 - call __PISTORE_STR + call core.__PISTORE_STR ld h, (ix+5) ld l, (ix+4) ld c, (hl) @@ -81,13 +81,13 @@ _test: ld l, c ex de, hl ld hl, _y - call __STORE_STR + call core.__STORE_STR _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -228,9 +228,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -238,37 +239,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -278,94 +280,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 79 "byrefstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -442,6 +446,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -471,6 +476,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -543,90 +549,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -648,132 +656,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -798,6 +811,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 80 "byrefstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -806,138 +820,144 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 81 "byrefstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 82 "byrefstr.bas" END diff --git a/tests/functional/byte_neq.asm b/tests/functional/byte_neq.asm index 6f85a2188..c14e76941 100644 --- a/tests/functional/byte_neq.asm +++ b/tests/functional/byte_neq.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) sub 5 jp z, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/byval32.asm b/tests/functional/byval32.asm index e68d252af..c5efbeb61 100644 --- a/tests/functional/byval32.asm +++ b/tests/functional/byval32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,17 +46,17 @@ _test: ld de, 0 ld hl, 0 ld bc, 4 - call __PSTORE32 + call core.__PSTORE32 ld l, (ix-4) ld h, (ix-3) ld e, (ix-2) ld d, (ix-1) ld bc, 4 - call __PSTORE32 + call core.__PSTORE32 ld hl, (_y) ld de, (_y + 2) ld bc, 4 - call __PSTORE32 + call core.__PSTORE32 ld l, (ix+4) ld h, (ix+5) ld e, (ix+6) @@ -75,34 +75,38 @@ _test__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstore32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" + push namespace core __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/pstore32.asm" ; Stores a 32 bit integer number (DE,HL) at (IX + BC) + push namespace core __PSTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc - jp __STORE32 + push hl + push ix + pop hl + add hl, bc + pop bc + jp __STORE32 + pop namespace #line 53 "byval32.bas" END diff --git a/tests/functional/byvalbyref.asm b/tests/functional/byvalbyref.asm index 1e991027e..c60753080 100644 --- a/tests/functional/byvalbyref.asm +++ b/tests/functional/byvalbyref.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_v) push af call _primero ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/castF16toF.asm b/tests/functional/castF16toF.asm index dfd243df9..e3cd81466 100644 --- a/tests/functional/castF16toF.asm +++ b/tests/functional/castF16toF.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00h DEFB 00h @@ -25,19 +25,19 @@ _a: DEFB 00h _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) - call __F16TOFREG + call core.__F16TOFREG ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,111 +49,116 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -161,44 +166,47 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 22 "castF16toF.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 23 "castF16toF.bas" END diff --git a/tests/functional/cast_ftoi16.asm b/tests/functional/cast_ftoi16.asm index 99be9d44f..4897c873c 100644 --- a/tests/functional/cast_ftoi16.asm +++ b/tests/functional/cast_ftoi16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,77 +46,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -133,10 +136,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 22 "cast_ftoi16.bas" END diff --git a/tests/functional/cast_ftoi32.asm b/tests/functional/cast_ftoi32.asm index bf260ac65..a20b46351 100644 --- a/tests/functional/cast_ftoi32.asm +++ b/tests/functional/cast_ftoi32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,77 +47,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -134,10 +137,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 23 "cast_ftoi32.bas" END diff --git a/tests/functional/cast_ftoi8.asm b/tests/functional/cast_ftoi8.asm index 6f5f07d21..26778a153 100644 --- a/tests/functional/cast_ftoi8.asm +++ b/tests/functional/cast_ftoi8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,77 +47,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -134,10 +137,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 23 "cast_ftoi8.bas" END diff --git a/tests/functional/cast_i8tof.asm b/tests/functional/cast_i8tof.asm index ef82224d6..9689cc0da 100644 --- a/tests/functional/cast_i8tof.asm +++ b/tests/functional/cast_i8tof.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) - call __I8TOFREG + call core.__I8TOFREG ld hl, _b - call __STOREF + call core.__STOREF ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,77 +51,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -138,106 +141,111 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 27 "cast_i8tof.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 28 "cast_i8tof.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 29 "cast_i8tof.bas" END diff --git a/tests/functional/chr.asm b/tests/functional/chr.asm index 57e54bec2..043bb173a 100644 --- a/tests/functional/chr.asm +++ b/tests/functional/chr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,46 +8,46 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld a, 33 ld (_b), a push af ld hl, 1 - call CHR + call core.CHR ex de, hl ld hl, _c - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -126,6 +126,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -155,6 +156,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -220,9 +222,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -230,37 +233,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -273,142 +277,146 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/chr.asm" + push namespace core CHR: ; Returns HL = Pointer to STRING (NULL if no memory) - ; Requires alloc.asm for dynamic memory heap. - ; Parameters: HL = Number of bytes to insert (already push onto the stack) - ; STACK => parameters (16 bit, only the High byte is considered) - ; Used registers A, A', BC, DE, HL, H'L' - PROC - LOCAL __POPOUT - LOCAL TMP + ; Requires alloc.asm for dynamic memory heap. + ; Parameters: HL = Number of bytes to insert (already push onto the stack) + ; STACK => parameters (16 bit, only the High byte is considered) + ; Used registers A, A', BC, DE, HL, H'L' + PROC + LOCAL __POPOUT + LOCAL TMP TMP EQU 23629 ; (DEST System variable) - ld a, h - or l - ret z ; If Number of parameters is ZERO, return NULL STRING - ld b, h - ld c, l - pop hl ; Return address - ld (TMP), hl - push bc - inc bc - inc bc ; BC = BC + 2 => (2 bytes for the length number) - call __MEM_ALLOC - pop bc - ld d, h - ld e, l ; Saves HL in DE - ld a, h - or l - jr z, __POPOUT ; No Memory, return - ld (hl), c - inc hl - ld (hl), b - inc hl + ld a, h + or l + ret z ; If Number of parameters is ZERO, return NULL STRING + ld b, h + ld c, l + pop hl ; Return address + ld (TMP), hl + push bc + inc bc + inc bc ; BC = BC + 2 => (2 bytes for the length number) + call __MEM_ALLOC + pop bc + ld d, h + ld e, l ; Saves HL in DE + ld a, h + or l + jr z, __POPOUT ; No Memory, return + ld (hl), c + inc hl + ld (hl), b + inc hl __POPOUT: ; Removes out of the stack every byte and return - ; If Zero Flag is set, don't store bytes in memory - ex af, af' ; Save Zero Flag - ld a, b - or c - jr z, __CHR_END - dec bc - pop af ; Next byte - ex af, af' ; Recovers Zero flag - jr z, __POPOUT - ex af, af' ; Saves Zero flag - ld (hl), a - inc hl - ex af, af' ; Recovers Zero Flag - jp __POPOUT + ; If Zero Flag is set, don't store bytes in memory + ex af, af' ; Save Zero Flag + ld a, b + or c + jr z, __CHR_END + dec bc + pop af ; Next byte + ex af, af' ; Recovers Zero flag + jr z, __POPOUT + ex af, af' ; Saves Zero flag + ld (hl), a + inc hl + ex af, af' ; Recovers Zero Flag + jp __POPOUT __CHR_END: - ld hl, (TMP) - push hl ; Restores return addr - ex de, hl ; Recovers original HL ptr - ret - ENDP + ld hl, (TMP) + push hl ; Restores return addr + ex de, hl ; Recovers original HL ptr + ret + ENDP + pop namespace #line 31 "chr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -550,94 +558,96 @@ __CHR_END: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -659,132 +669,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -809,6 +824,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 32 "chr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -817,29 +833,31 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 33 "chr.bas" END diff --git a/tests/functional/chr0.asm b/tests/functional/chr0.asm index debff6cc1..5831fd649 100644 --- a/tests/functional/chr0.asm +++ b/tests/functional/chr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 64 ld (_a), a ld a, 65 @@ -40,16 +40,16 @@ __MAIN_PROGRAM__: inc a push af ld hl, 2 - call CHR + call core.CHR ex de, hl ld hl, _c - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -125,6 +125,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -154,6 +155,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -219,9 +221,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -229,37 +232,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -272,142 +276,146 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/chr.asm" + push namespace core CHR: ; Returns HL = Pointer to STRING (NULL if no memory) - ; Requires alloc.asm for dynamic memory heap. - ; Parameters: HL = Number of bytes to insert (already push onto the stack) - ; STACK => parameters (16 bit, only the High byte is considered) - ; Used registers A, A', BC, DE, HL, H'L' - PROC - LOCAL __POPOUT - LOCAL TMP + ; Requires alloc.asm for dynamic memory heap. + ; Parameters: HL = Number of bytes to insert (already push onto the stack) + ; STACK => parameters (16 bit, only the High byte is considered) + ; Used registers A, A', BC, DE, HL, H'L' + PROC + LOCAL __POPOUT + LOCAL TMP TMP EQU 23629 ; (DEST System variable) - ld a, h - or l - ret z ; If Number of parameters is ZERO, return NULL STRING - ld b, h - ld c, l - pop hl ; Return address - ld (TMP), hl - push bc - inc bc - inc bc ; BC = BC + 2 => (2 bytes for the length number) - call __MEM_ALLOC - pop bc - ld d, h - ld e, l ; Saves HL in DE - ld a, h - or l - jr z, __POPOUT ; No Memory, return - ld (hl), c - inc hl - ld (hl), b - inc hl + ld a, h + or l + ret z ; If Number of parameters is ZERO, return NULL STRING + ld b, h + ld c, l + pop hl ; Return address + ld (TMP), hl + push bc + inc bc + inc bc ; BC = BC + 2 => (2 bytes for the length number) + call __MEM_ALLOC + pop bc + ld d, h + ld e, l ; Saves HL in DE + ld a, h + or l + jr z, __POPOUT ; No Memory, return + ld (hl), c + inc hl + ld (hl), b + inc hl __POPOUT: ; Removes out of the stack every byte and return - ; If Zero Flag is set, don't store bytes in memory - ex af, af' ; Save Zero Flag - ld a, b - or c - jr z, __CHR_END - dec bc - pop af ; Next byte - ex af, af' ; Recovers Zero flag - jr z, __POPOUT - ex af, af' ; Saves Zero flag - ld (hl), a - inc hl - ex af, af' ; Recovers Zero Flag - jp __POPOUT + ; If Zero Flag is set, don't store bytes in memory + ex af, af' ; Save Zero Flag + ld a, b + or c + jr z, __CHR_END + dec bc + pop af ; Next byte + ex af, af' ; Recovers Zero flag + jr z, __POPOUT + ex af, af' ; Saves Zero flag + ld (hl), a + inc hl + ex af, af' ; Recovers Zero Flag + jp __POPOUT __CHR_END: - ld hl, (TMP) - push hl ; Restores return addr - ex de, hl ; Recovers original HL ptr - ret - ENDP + ld hl, (TMP) + push hl ; Restores return addr + ex de, hl ; Recovers original HL ptr + ret + ENDP + pop namespace #line 30 "chr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -484,118 +492,122 @@ __CHR_END: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 31 "chr0.bas" END diff --git a/tests/functional/chr1.asm b/tests/functional/chr1.asm index 4c54ddfe4..6931ba677 100644 --- a/tests/functional/chr1.asm +++ b/tests/functional/chr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -125,6 +125,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -154,6 +155,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -279,9 +281,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -289,37 +292,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -332,90 +336,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -485,94 +491,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -594,132 +602,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -744,5 +757,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 25 "chr1.bas" END diff --git a/tests/functional/circle.asm b/tests/functional/circle.asm index 3e15371eb..e9fa8a38e 100644 --- a/tests/functional/circle.asm +++ b/tests/functional/circle.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,88 +8,88 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 _c: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 11 push af ld a, 22 push af ld a, 33 - call CIRCLE + call core.CIRCLE ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, 22 push af ld a, 33 - call CIRCLE + call core.CIRCLE ld a, 11 push af ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, 33 - call CIRCLE + call core.CIRCLE ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, 33 - call CIRCLE + call core.CIRCLE ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, (_c) ld de, (_c + 1) ld bc, (_c + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l - call CIRCLE + call core.CIRCLE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -105,6 +105,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -134,6 +135,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" ; MIXED __FASTCAL__ / __CALLE__ PLOT Function @@ -143,93 +145,100 @@ __STOP: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -237,7 +246,9 @@ __CLS_SCR: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -292,29 +303,31 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + push namespace core PLOT: - PROC - LOCAL PLOT_SUB - LOCAL PIXEL_ADDR - LOCAL COORDS - LOCAL __PLOT_ERR + PROC + LOCAL PLOT_SUB + LOCAL PIXEL_ADDR + LOCAL COORDS + LOCAL __PLOT_ERR LOCAL P_FLAG LOCAL __PLOT_OVER1 P_FLAG EQU 23697 - pop hl - ex (sp), hl ; Callee - ld b, a - ld c, h -#line 35 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 41 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" - ld a, 191 - cp b - jr c, __PLOT_ERR ; jr is faster here (#1) + pop hl + ex (sp), hl ; Callee + ld b, a + ld c, h +#line 37 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 43 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + ld a, 191 + cp b + jr c, __PLOT_ERR ; jr is faster here (#1) __PLOT: ; __FASTCALL__ entry (b, c) = pixel coords (y, x) - ld (COORDS), bc ; Saves current point - ld a, 191 ; Max y coord - call PIXEL_ADDR + ld (COORDS), bc ; Saves current point + ld a, 191 ; Max y coord + call PIXEL_ADDR res 6, h ; Starts from 0 ld bc, (SCREEN_ADDR) add hl, bc ; Now current offset @@ -346,247 +359,253 @@ __PLOT_ERR: PLOT_SUB EQU 22ECh PIXEL_ADDR EQU 22ACh COORDS EQU 5C7Dh - ENDP + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" ; Draws a circle at X, Y of radius R ; X, Y on the Stack, R in accumulator (Byte) - PROC - LOCAL __CIRCLE_ERROR - LOCAL __CIRCLE_LOOP - LOCAL __CIRCLE_NEXT + push namespace core + PROC + LOCAL __CIRCLE_ERROR + LOCAL __CIRCLE_LOOP + LOCAL __CIRCLE_NEXT __CIRCLE_ERROR: - jp __OUT_OF_SCREEN_ERR + jp __OUT_OF_SCREEN_ERR CIRCLE: - ;; Entry point - pop hl ; Return Address - pop de ; D = Y - ex (sp), hl ; __CALLEE__ convention - ld e, h ; E = X - ld h, a ; H = R -#line 31 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" - ld a, h - add a, d - sub 192 - jr nc, __CIRCLE_ERROR - ld a, d - sub h - jr c, __CIRCLE_ERROR - ld a, e - sub h - jr c, __CIRCLE_ERROR - ld a, h - add a, e - jr c, __CIRCLE_ERROR + ;; Entry point + pop hl ; Return Address + pop de ; D = Y + ex (sp), hl ; __CALLEE__ convention + ld e, h ; E = X + ld h, a ; H = R +#line 33 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" +#line 39 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" + ld a, h + add a, d + sub 192 + jr nc, __CIRCLE_ERROR + ld a, d + sub h + jr c, __CIRCLE_ERROR + ld a, e + sub h + jr c, __CIRCLE_ERROR + ld a, h + add a, e + jr c, __CIRCLE_ERROR ; __FASTCALL__ Entry: D, E = Y, X point of the center ; A = Radious __CIRCLE: - push de - ld a, h - exx - pop de ; D'E' = x0, y0 - ld h, a ; H' = r - ld c, e - ld a, h - add a, d - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 + r) - ld b, d - ld a, h - add a, e - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 + r, y0) - ld c, e - ld a, d - sub h - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 - r) - ld b, d - ld a, e - sub h - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 - r, y0) - exx - ld b, 0 ; B = x = 0 - ld c, h ; C = y = Radius - ld hl, 1 - or a - sbc hl, bc ; HL = f = 1 - radius - ex de, hl - ld hl, 0 - or a - sbc hl, bc ; HL = -radius - add hl, hl ; HL = -2 * radius - ex de, hl ; DE = -2 * radius = ddF_y, HL = f - xor a ; A = ddF_x = 0 - ex af, af' ; Saves it + push de + ld a, h + exx + pop de ; D'E' = x0, y0 + ld h, a ; H' = r + ld c, e + ld a, h + add a, d + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 + r) + ld b, d + ld a, h + add a, e + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 + r, y0) + ld c, e + ld a, d + sub h + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 - r) + ld b, d + ld a, e + sub h + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 - r, y0) + exx + ld b, 0 ; B = x = 0 + ld c, h ; C = y = Radius + ld hl, 1 + or a + sbc hl, bc ; HL = f = 1 - radius + ex de, hl + ld hl, 0 + or a + sbc hl, bc ; HL = -radius + add hl, hl ; HL = -2 * radius + ex de, hl ; DE = -2 * radius = ddF_y, HL = f + xor a ; A = ddF_x = 0 + ex af, af' ; Saves it __CIRCLE_LOOP: - ld a, b - cp c - ret nc ; Returns when x >= y - bit 7, h ; HL >= 0? : if (f >= 0)... - jp nz, __CIRCLE_NEXT - dec c ; y-- - inc de - inc de ; ddF_y += 2 - add hl, de ; f += ddF_y + ld a, b + cp c + ret nc ; Returns when x >= y + bit 7, h ; HL >= 0? : if (f >= 0)... + jp nz, __CIRCLE_NEXT + dec c ; y-- + inc de + inc de ; ddF_y += 2 + add hl, de ; f += ddF_y __CIRCLE_NEXT: - inc b ; x++ - ex af, af' - add a, 2 ; 1 Cycle faster than inc a, inc a - inc hl ; f++ - push af - add a, l - ld l, a - ld a, h - adc a, 0 ; f = f + ddF_x - ld h, a - pop af - ex af, af' - push bc - exx - pop hl ; H'L' = Y, X - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - sub h - ld c, a ; C = x0 - y - call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - sub h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) - exx - jp __CIRCLE_LOOP + inc b ; x++ + ex af, af' + add a, 2 ; 1 Cycle faster than inc a, inc a + inc hl ; f++ + push af + add a, l + ld l, a + ld a, h + adc a, 0 ; f = f + ddF_x + ld h, a + pop af + ex af, af' + push bc + exx + pop hl ; H'L' = Y, X + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + sub h + ld c, a ; C = x0 - y + call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + sub h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) + exx + jp __CIRCLE_LOOP __CIRCLE_PLOT: - ; Plots a point of the circle, preserving HL and DE - push hl - push de - call __PLOT - pop de - pop hl - ret - ENDP + ; Plots a point of the circle, preserving HL and DE + push hl + push de + call __PLOT + pop de + pop hl + ret + ENDP + pop namespace #line 75 "circle.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -603,10 +622,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 76 "circle.bas" END diff --git a/tests/functional/co.asm b/tests/functional/co.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/co.asm +++ b/tests/functional/co.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/code00.asm b/tests/functional/code00.asm index 53b16691b..89cec38c6 100644 --- a/tests/functional/code00.asm +++ b/tests/functional/code00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 0 push hl @@ -35,13 +35,13 @@ __MAIN_PROGRAM__: push hl ld a, 1 push af - call LOAD_CODE + call core.LOAD_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -178,9 +178,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -188,37 +189,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -228,94 +230,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -324,70 +328,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -417,49 +426,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -467,296 +482,316 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -811,424 +846,428 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 6 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + push namespace core LOAD_CODE: ; This function will implement the LOAD CODE Routine ; Parameters in the stack are HL => String with LOAD name @@ -1251,11 +1290,11 @@ LOAD_CODE: LOCAL TMP_SP MEM0 EQU 5C92h ; Temporary memory buffer HEAD1 EQU MEM0 + 8 ; Uses CALC Mem for temporary storage - ; Must skip first 8 bytes used by - ; PRINT routine + ; Must skip first 8 bytes used by + ; PRINT routine TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage TMP_SP EQU TMP_HEADER + 2 ; Temporary SP storage -#line 40 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 42 "/zxbasic/src/arch/zx48k/library-asm/load.asm" TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG pop hl ; Return address pop af ; A = 1 => LOAD; A = 0 => VERIFY @@ -1327,26 +1366,26 @@ LD_LOOK_H: xor a ; reset zero flag scf ; set carry flag call LD_BYTES ; routine LD-BYTES loads a header from tape - ; to second descriptor. + ; to second descriptor. pop ix ; restore IX jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found. ld c, 80h ; C has bit 7 set to indicate header type mismatch as - ; a default startpoint. + ; a default startpoint. ld a, (ix + 0) ; compare loaded type cp 3 ; with expected bytes header jr nz, LD_TYPE ; forward to LD-TYPE with mis-match. ld c, -10 ; set C to minus ten - will count characters - ; up to zero. + ; up to zero. LD_TYPE: cp 4 ; check if type in acceptable range 0 - 3. jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over. - ; else A indicates type 0-3. + ; else A indicates type 0-3. call PRINT_TAPE_MESSAGES; Print tape msg -#line 148 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 150 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld hl, HEAD1 + 1 ; point HL to 1st descriptor. ld de, (TMP_HEADER) ; point DE to 2nd descriptor. ld b, 10 ; the count will be ten characters for the - ; filename. + ; filename. ld a, (hl) ; fetch first character and test for inc a ; value 255. jr nz, LD_NAME ; forward to LD-NAME if not the wildcard. @@ -1369,14 +1408,14 @@ LD_NAME: ;; LD-CH-PR LD_CH_PR: call __PRINTCHAR ; PRINT-A prints character -#line 184 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 186 "/zxbasic/src/arch/zx48k/library-asm/load.asm" djnz LD_NAME ; loop back to LD-NAME for ten characters. bit 7, c ; test if all matched jr nz, LD_LOOK_H ; back to LD-LOOK-H if not ; else print a terminal carriage return. ld a, 0Dh ; prepare carriage return. call __PRINTCHAR ; PRINT-A outputs it. -#line 195 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 197 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld a, (HEAD1) cp 03 ; Only "bytes:" header is used un ZX BASIC jr nz, LD_LOOK_H @@ -1391,7 +1430,7 @@ VR_CONTROL: ld l, a or h ; check length of old for zero. (Carry reset) jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified - ; e.g. LOAD "x" CODE + ; e.g. LOAD "x" CODE sbc hl, de jr nz, LOAD_ERROR ; Lengths don't match VR_CONT_1: @@ -1442,7 +1481,7 @@ LD_BYTES_RET: LD_BYTES_NOINTER: ex af, af' ret -#line 278 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 280 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ENDP PRINT_TAPE_MESSAGES: PROC @@ -1466,11 +1505,11 @@ LOOK_NEXT_TAPE_MSG: inc hl ; Point to next char cp (hl) ; Is it 0Dh? jr nz, LOOK_NEXT_TAPE_MSG - ; Ok next message found + ; Ok next message found djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip PRINT_TAPE_MSG: - ; Ok. This will print bytes after (HL) - ; until one of them has bit 7 set + ; Ok. This will print bytes after (HL) + ; until one of them has bit 7 set ld a, (hl) and 7Fh ; Clear bit 7 of A call __PRINTCHAR @@ -1481,7 +1520,8 @@ PRINT_TAPE_MSG: pop bc ret ENDP -#line 332 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + pop namespace #line 29 "code00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -1555,124 +1595,128 @@ PRINT_TAPE_MSG: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 30 "code00.bas" END diff --git a/tests/functional/code01.asm b/tests/functional/code01.asm index a6a6b1402..1e3b0ecd7 100644 --- a/tests/functional/code01.asm +++ b/tests/functional/code01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 16384 push hl @@ -35,13 +35,13 @@ __MAIN_PROGRAM__: push hl ld a, 1 push af - call LOAD_CODE + call core.LOAD_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -178,9 +178,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -188,37 +189,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -228,94 +230,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -324,70 +328,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -417,49 +426,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -467,296 +482,316 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -811,424 +846,428 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 6 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + push namespace core LOAD_CODE: ; This function will implement the LOAD CODE Routine ; Parameters in the stack are HL => String with LOAD name @@ -1251,11 +1290,11 @@ LOAD_CODE: LOCAL TMP_SP MEM0 EQU 5C92h ; Temporary memory buffer HEAD1 EQU MEM0 + 8 ; Uses CALC Mem for temporary storage - ; Must skip first 8 bytes used by - ; PRINT routine + ; Must skip first 8 bytes used by + ; PRINT routine TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage TMP_SP EQU TMP_HEADER + 2 ; Temporary SP storage -#line 40 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 42 "/zxbasic/src/arch/zx48k/library-asm/load.asm" TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG pop hl ; Return address pop af ; A = 1 => LOAD; A = 0 => VERIFY @@ -1327,26 +1366,26 @@ LD_LOOK_H: xor a ; reset zero flag scf ; set carry flag call LD_BYTES ; routine LD-BYTES loads a header from tape - ; to second descriptor. + ; to second descriptor. pop ix ; restore IX jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found. ld c, 80h ; C has bit 7 set to indicate header type mismatch as - ; a default startpoint. + ; a default startpoint. ld a, (ix + 0) ; compare loaded type cp 3 ; with expected bytes header jr nz, LD_TYPE ; forward to LD-TYPE with mis-match. ld c, -10 ; set C to minus ten - will count characters - ; up to zero. + ; up to zero. LD_TYPE: cp 4 ; check if type in acceptable range 0 - 3. jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over. - ; else A indicates type 0-3. + ; else A indicates type 0-3. call PRINT_TAPE_MESSAGES; Print tape msg -#line 148 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 150 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld hl, HEAD1 + 1 ; point HL to 1st descriptor. ld de, (TMP_HEADER) ; point DE to 2nd descriptor. ld b, 10 ; the count will be ten characters for the - ; filename. + ; filename. ld a, (hl) ; fetch first character and test for inc a ; value 255. jr nz, LD_NAME ; forward to LD-NAME if not the wildcard. @@ -1369,14 +1408,14 @@ LD_NAME: ;; LD-CH-PR LD_CH_PR: call __PRINTCHAR ; PRINT-A prints character -#line 184 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 186 "/zxbasic/src/arch/zx48k/library-asm/load.asm" djnz LD_NAME ; loop back to LD-NAME for ten characters. bit 7, c ; test if all matched jr nz, LD_LOOK_H ; back to LD-LOOK-H if not ; else print a terminal carriage return. ld a, 0Dh ; prepare carriage return. call __PRINTCHAR ; PRINT-A outputs it. -#line 195 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 197 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld a, (HEAD1) cp 03 ; Only "bytes:" header is used un ZX BASIC jr nz, LD_LOOK_H @@ -1391,7 +1430,7 @@ VR_CONTROL: ld l, a or h ; check length of old for zero. (Carry reset) jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified - ; e.g. LOAD "x" CODE + ; e.g. LOAD "x" CODE sbc hl, de jr nz, LOAD_ERROR ; Lengths don't match VR_CONT_1: @@ -1442,7 +1481,7 @@ LD_BYTES_RET: LD_BYTES_NOINTER: ex af, af' ret -#line 278 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 280 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ENDP PRINT_TAPE_MESSAGES: PROC @@ -1466,11 +1505,11 @@ LOOK_NEXT_TAPE_MSG: inc hl ; Point to next char cp (hl) ; Is it 0Dh? jr nz, LOOK_NEXT_TAPE_MSG - ; Ok next message found + ; Ok next message found djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip PRINT_TAPE_MSG: - ; Ok. This will print bytes after (HL) - ; until one of them has bit 7 set + ; Ok. This will print bytes after (HL) + ; until one of them has bit 7 set ld a, (hl) and 7Fh ; Clear bit 7 of A call __PRINTCHAR @@ -1481,7 +1520,8 @@ PRINT_TAPE_MSG: pop bc ret ENDP -#line 332 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + pop namespace #line 29 "code01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -1555,124 +1595,128 @@ PRINT_TAPE_MSG: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 30 "code01.bas" END diff --git a/tests/functional/code02.asm b/tests/functional/code02.asm index 1ff2d5d1a..59ae3b73e 100644 --- a/tests/functional/code02.asm +++ b/tests/functional/code02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 16384 push hl @@ -35,13 +35,13 @@ __MAIN_PROGRAM__: push hl ld a, 1 push af - call LOAD_CODE + call core.LOAD_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -178,9 +178,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -188,37 +189,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -228,94 +230,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -324,70 +328,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -417,49 +426,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -467,296 +482,316 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -811,424 +846,428 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 6 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + push namespace core LOAD_CODE: ; This function will implement the LOAD CODE Routine ; Parameters in the stack are HL => String with LOAD name @@ -1251,11 +1290,11 @@ LOAD_CODE: LOCAL TMP_SP MEM0 EQU 5C92h ; Temporary memory buffer HEAD1 EQU MEM0 + 8 ; Uses CALC Mem for temporary storage - ; Must skip first 8 bytes used by - ; PRINT routine + ; Must skip first 8 bytes used by + ; PRINT routine TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage TMP_SP EQU TMP_HEADER + 2 ; Temporary SP storage -#line 40 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 42 "/zxbasic/src/arch/zx48k/library-asm/load.asm" TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG pop hl ; Return address pop af ; A = 1 => LOAD; A = 0 => VERIFY @@ -1327,26 +1366,26 @@ LD_LOOK_H: xor a ; reset zero flag scf ; set carry flag call LD_BYTES ; routine LD-BYTES loads a header from tape - ; to second descriptor. + ; to second descriptor. pop ix ; restore IX jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found. ld c, 80h ; C has bit 7 set to indicate header type mismatch as - ; a default startpoint. + ; a default startpoint. ld a, (ix + 0) ; compare loaded type cp 3 ; with expected bytes header jr nz, LD_TYPE ; forward to LD-TYPE with mis-match. ld c, -10 ; set C to minus ten - will count characters - ; up to zero. + ; up to zero. LD_TYPE: cp 4 ; check if type in acceptable range 0 - 3. jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over. - ; else A indicates type 0-3. + ; else A indicates type 0-3. call PRINT_TAPE_MESSAGES; Print tape msg -#line 148 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 150 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld hl, HEAD1 + 1 ; point HL to 1st descriptor. ld de, (TMP_HEADER) ; point DE to 2nd descriptor. ld b, 10 ; the count will be ten characters for the - ; filename. + ; filename. ld a, (hl) ; fetch first character and test for inc a ; value 255. jr nz, LD_NAME ; forward to LD-NAME if not the wildcard. @@ -1369,14 +1408,14 @@ LD_NAME: ;; LD-CH-PR LD_CH_PR: call __PRINTCHAR ; PRINT-A prints character -#line 184 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 186 "/zxbasic/src/arch/zx48k/library-asm/load.asm" djnz LD_NAME ; loop back to LD-NAME for ten characters. bit 7, c ; test if all matched jr nz, LD_LOOK_H ; back to LD-LOOK-H if not ; else print a terminal carriage return. ld a, 0Dh ; prepare carriage return. call __PRINTCHAR ; PRINT-A outputs it. -#line 195 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 197 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld a, (HEAD1) cp 03 ; Only "bytes:" header is used un ZX BASIC jr nz, LD_LOOK_H @@ -1391,7 +1430,7 @@ VR_CONTROL: ld l, a or h ; check length of old for zero. (Carry reset) jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified - ; e.g. LOAD "x" CODE + ; e.g. LOAD "x" CODE sbc hl, de jr nz, LOAD_ERROR ; Lengths don't match VR_CONT_1: @@ -1442,7 +1481,7 @@ LD_BYTES_RET: LD_BYTES_NOINTER: ex af, af' ret -#line 278 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 280 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ENDP PRINT_TAPE_MESSAGES: PROC @@ -1466,11 +1505,11 @@ LOOK_NEXT_TAPE_MSG: inc hl ; Point to next char cp (hl) ; Is it 0Dh? jr nz, LOOK_NEXT_TAPE_MSG - ; Ok next message found + ; Ok next message found djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip PRINT_TAPE_MSG: - ; Ok. This will print bytes after (HL) - ; until one of them has bit 7 set + ; Ok. This will print bytes after (HL) + ; until one of them has bit 7 set ld a, (hl) and 7Fh ; Clear bit 7 of A call __PRINTCHAR @@ -1481,7 +1520,8 @@ PRINT_TAPE_MSG: pop bc ret ENDP -#line 332 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + pop namespace #line 29 "code02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -1555,124 +1595,128 @@ PRINT_TAPE_MSG: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 30 "code02.bas" END diff --git a/tests/functional/codecrash1.asm b/tests/functional/codecrash1.asm index a426bd982..604bd647d 100644 --- a/tests/functional/codecrash1.asm +++ b/tests/functional/codecrash1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) xor a - call __ASC + call core.__ASC ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -174,9 +174,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -184,37 +185,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -224,118 +226,122 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/asc.asm" + push namespace core __ASC: - PROC - LOCAL __ASC_END - ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + PROC + LOCAL __ASC_END + ex af, af' ; Saves free_mem flag + ld a, h + or l + ret z ; NULL? return + ld c, (hl) + inc hl + ld b, (hl) + ld a, b + or c + jr z, __ASC_END ; No length? return + inc hl + ld a, (hl) dec hl __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed - ex af, af' ; Recover result - ret - ENDP + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + ex af, af' ; Recover result + ret + ENDP + pop namespace #line 21 "codecrash1.bas" END diff --git a/tests/functional/codecrash2.asm b/tests/functional/codecrash2.asm index fbeca8896..02e811da2 100644 --- a/tests/functional/codecrash2.asm +++ b/tests/functional/codecrash2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_b) ld hl, (_b) - call __ADDSTR + call core.__ADDSTR ld a, 1 - call __ASC + call core.__ASC ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -176,9 +176,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -186,37 +187,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -226,119 +228,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/asc.asm" + push namespace core __ASC: - PROC - LOCAL __ASC_END - ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + PROC + LOCAL __ASC_END + ex af, af' ; Saves free_mem flag + ld a, h + or l + ret z ; NULL? return + ld c, (hl) + inc hl + ld b, (hl) + ld a, b + or c + jr z, __ASC_END ; No length? return + inc hl + ld a, (hl) dec hl __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed - ex af, af' ; Recover result - ret - ENDP + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + ex af, af' ; Recover result + ret + ENDP + pop namespace #line 23 "codecrash2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -404,6 +410,7 @@ __ASC_END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -433,6 +440,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -445,197 +453,203 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 24 "codecrash2.bas" END diff --git a/tests/functional/codecrash3.asm b/tests/functional/codecrash3.asm index b3317c7e3..31eb833f3 100644 --- a/tests/functional/codecrash3.asm +++ b/tests/functional/codecrash3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call INKEY +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.INKEY ld a, 1 - call __ASC + call core.__ASC ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -172,9 +172,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -182,37 +183,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -222,119 +224,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/asc.asm" + push namespace core __ASC: - PROC - LOCAL __ASC_END - ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + PROC + LOCAL __ASC_END + ex af, af' ; Saves free_mem flag + ld a, h + or l + ret z ; NULL? return + ld c, (hl) + inc hl + ld b, (hl) + ld a, b + or c + jr z, __ASC_END ; No length? return + inc hl + ld a, (hl) dec hl __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed - ex af, af' ; Recover result - ret - ENDP + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + ex af, af' ; Recover result + ret + ENDP + pop namespace #line 21 "codecrash3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" ; INKEY Function @@ -404,6 +410,7 @@ __ASC_END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -433,6 +440,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -445,132 +453,136 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" + push namespace core INKEY: - PROC - LOCAL __EMPTY_INKEY - LOCAL KEY_SCAN - LOCAL KEY_TEST - LOCAL KEY_CODE - ld bc, 3 ; 1 char length string - call __MEM_ALLOC - ld a, h - or l - ret z ; Return if NULL (No memory) - push hl ; Saves memory pointer - call KEY_SCAN - jp nz, __EMPTY_INKEY - call KEY_TEST - jp nc, __EMPTY_INKEY - dec d ; D is expected to be FLAGS so set bit 3 $FF - ; 'L' Mode so no keywords. - ld e, a ; main key to A - ; C is MODE 0 'KLC' from above still. - call KEY_CODE ; routine K-DECODE - pop hl - ld (hl), 1 - inc hl - ld (hl), 0 - inc hl - ld (hl), a - dec hl - dec hl ; HL Points to string result - ret + PROC + LOCAL __EMPTY_INKEY + LOCAL KEY_SCAN + LOCAL KEY_TEST + LOCAL KEY_CODE + ld bc, 3 ; 1 char length string + call __MEM_ALLOC + ld a, h + or l + ret z ; Return if NULL (No memory) + push hl ; Saves memory pointer + call KEY_SCAN + jp nz, __EMPTY_INKEY + call KEY_TEST + jp nc, __EMPTY_INKEY + dec d ; D is expected to be FLAGS so set bit 3 $FF + ; 'L' Mode so no keywords. + ld e, a ; main key to A + ; C is MODE 0 'KLC' from above still. + call KEY_CODE ; routine K-DECODE + pop hl + ld (hl), 1 + inc hl + ld (hl), 0 + inc hl + ld (hl), a + dec hl + dec hl ; HL Points to string result + ret __EMPTY_INKEY: - pop hl - xor a - ld (hl), a - inc hl - ld (hl), a - dec hl - ret + pop hl + xor a + ld (hl), a + inc hl + ld (hl), a + dec hl + ret KEY_SCAN EQU 028Eh KEY_TEST EQU 031Eh KEY_CODE EQU 0333h - ENDP + ENDP + pop namespace #line 22 "codecrash3.bas" END diff --git a/tests/functional/codecrash4.asm b/tests/functional/codecrash4.asm index 47560edd4..354452825 100644 --- a/tests/functional/codecrash4.asm +++ b/tests/functional/codecrash4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,47 +8,47 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) xor a - call __ASC + call core.__ASC ld (_a), a ld de, (_b) ld hl, (_b) - call __ADDSTR + call core.__ADDSTR ld a, 1 - call __ASC + call core.__ASC ld (_a), a - call INKEY + call core.INKEY ld a, 1 - call __ASC + call core.__ASC ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -184,9 +184,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -194,37 +195,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -234,119 +236,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/asc.asm" + push namespace core __ASC: - PROC - LOCAL __ASC_END - ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + PROC + LOCAL __ASC_END + ex af, af' ; Saves free_mem flag + ld a, h + or l + ret z ; NULL? return + ld c, (hl) + inc hl + ld b, (hl) + ld a, b + or c + jr z, __ASC_END ; No length? return + inc hl + ld a, (hl) dec hl __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed - ex af, af' ; Recover result - ret - ENDP + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + ex af, af' ; Recover result + ret + ENDP + pop namespace #line 31 "codecrash4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" ; INKEY Function @@ -416,6 +422,7 @@ __ASC_END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -445,6 +452,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -457,241 +465,249 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" + push namespace core INKEY: - PROC - LOCAL __EMPTY_INKEY - LOCAL KEY_SCAN - LOCAL KEY_TEST - LOCAL KEY_CODE - ld bc, 3 ; 1 char length string - call __MEM_ALLOC - ld a, h - or l - ret z ; Return if NULL (No memory) - push hl ; Saves memory pointer - call KEY_SCAN - jp nz, __EMPTY_INKEY - call KEY_TEST - jp nc, __EMPTY_INKEY - dec d ; D is expected to be FLAGS so set bit 3 $FF - ; 'L' Mode so no keywords. - ld e, a ; main key to A - ; C is MODE 0 'KLC' from above still. - call KEY_CODE ; routine K-DECODE - pop hl - ld (hl), 1 - inc hl - ld (hl), 0 - inc hl - ld (hl), a - dec hl - dec hl ; HL Points to string result - ret + PROC + LOCAL __EMPTY_INKEY + LOCAL KEY_SCAN + LOCAL KEY_TEST + LOCAL KEY_CODE + ld bc, 3 ; 1 char length string + call __MEM_ALLOC + ld a, h + or l + ret z ; Return if NULL (No memory) + push hl ; Saves memory pointer + call KEY_SCAN + jp nz, __EMPTY_INKEY + call KEY_TEST + jp nc, __EMPTY_INKEY + dec d ; D is expected to be FLAGS so set bit 3 $FF + ; 'L' Mode so no keywords. + ld e, a ; main key to A + ; C is MODE 0 'KLC' from above still. + call KEY_CODE ; routine K-DECODE + pop hl + ld (hl), 1 + inc hl + ld (hl), 0 + inc hl + ld (hl), a + dec hl + dec hl ; HL Points to string result + ret __EMPTY_INKEY: - pop hl - xor a - ld (hl), a - inc hl - ld (hl), a - dec hl - ret + pop hl + xor a + ld (hl), a + inc hl + ld (hl), a + dec hl + ret KEY_SCAN EQU 028Eh KEY_TEST EQU 031Eh KEY_CODE EQU 0333h - ENDP + ENDP + pop namespace #line 32 "codecrash4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 33 "codecrash4.bas" END diff --git a/tests/functional/codecrash5.asm b/tests/functional/codecrash5.asm index 307b11dce..3d0ff7bcc 100644 --- a/tests/functional/codecrash5.asm +++ b/tests/functional/codecrash5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _c - call __STORE_STR + call core.__STORE_STR ld hl, (_c) - call __LOADSTR + call core.__LOADSTR push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,19 +57,19 @@ _test: ld l, (ix+4) ld h, (ix+5) xor a - call __ASC + call core.__ASC ld (ix-1), a ld l, (ix+4) ld h, (ix+5) xor a - call __ASC + call core.__ASC ld (ix-2), a _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -209,9 +209,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -219,37 +220,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -259,119 +261,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/asc.asm" + push namespace core __ASC: - PROC - LOCAL __ASC_END - ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + PROC + LOCAL __ASC_END + ex af, af' ; Saves free_mem flag + ld a, h + or l + ret z ; NULL? return + ld c, (hl) + inc hl + ld b, (hl) + ld a, b + or c + jr z, __ASC_END ; No length? return + inc hl + ld a, (hl) dec hl __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed - ex af, af' ; Recover result - ret - ENDP + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + ex af, af' ; Recover result + ret + ENDP + pop namespace #line 58 "codecrash5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -437,6 +443,7 @@ __ASC_END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -466,6 +473,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -478,125 +486,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 60 "codecrash5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -690,132 +702,137 @@ __LOADSTR: ; __FASTCALL__ entry ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -840,5 +857,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 61 "codecrash5.bas" END diff --git a/tests/functional/coercion1.asm b/tests/functional/coercion1.asm index 0647358a0..801622b62 100644 --- a/tests/functional/coercion1.asm +++ b/tests/functional/coercion1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,71 +8,71 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 _c: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l - call BORDER + call core.BORDER ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l - call BORDER + call core.BORDER ld hl, _a + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 083h ld de, 00020h ld bc, 00000h - call __MULF + call core.__MULF push bc push de push af ld a, 083h ld de, 000A0h ld bc, 00000h - call __DIVF + call core.__DIVF ld hl, 00000h push hl ld hl, 00000h push hl ld h, 082h push hl - call __ADDF - call __FTOU32REG + call core.__ADDF + call core.__FTOU32REG ld a, l - call BORDER + call core.BORDER ld a, (_c) - call BORDER + call core.BORDER ld a, (_c) ld h, 3 - call __MUL8_FAST - call BORDER + call core.__MUL8_FAST + call core.BORDER ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -87,12 +87,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -107,19 +108,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -129,24 +131,29 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 58 "coercion1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/border.asm" ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core BORDER EQU 229Bh + pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) #line 59 "coercion1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/divf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -176,6 +183,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/divf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -185,116 +193,121 @@ __STOP: ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __DIVF: ; Division - PROC - LOCAL __DIVBYZERO - LOCAL TMP, ERR_SP + PROC + LOCAL __DIVBYZERO + LOCAL TMP, ERR_SP TMP EQU 23629 ;(DEST) ERR_SP EQU 23613 - call __FPSTACK_PUSH2 - ld hl, (ERR_SP) - ld (TMP), hl - ld hl, __DIVBYZERO - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - ; ------------- ROM DIV - rst 28h - defb 01h ; EXCHANGE - defb 05h ; DIV - defb 38h; ; END CALC - pop hl - ld hl, (TMP) - ld (ERR_SP), hl - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ld hl, (ERR_SP) + ld (TMP), hl + ld hl, __DIVBYZERO + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl + ; ------------- ROM DIV + rst 28h + defb 01h ; EXCHANGE + defb 05h ; DIV + defb 38h; ; END CALC + pop hl + ld hl, (TMP) + ld (ERR_SP), hl + jp __FPSTACK_POP __DIVBYZERO: - ld hl, (TMP) - ld (ERR_SP), hl - ld a, ERROR_NumberTooBig - ld (ERR_NR), a - ; Returns 0 on DIV BY ZERO error - xor a - ld b, a - ld c, a - ld d, a - ld e, a - ret - ENDP + ld hl, (TMP) + ld (ERR_SP), hl + ld a, ERROR_NumberTooBig + ld (ERR_NR), a + ; Returns 0 on DIV BY ZERO error + xor a + ld b, a + ld c, a + ld d, a + ld e, a + ret + ENDP + pop namespace #line 60 "coercion1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -311,21 +324,23 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 61 "coercion1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -359,8 +374,9 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 62 "coercion1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- @@ -371,19 +387,22 @@ __MUL8B: ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 63 "coercion1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -404,5 +423,6 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 64 "coercion1.bas" END diff --git a/tests/functional/coercion3.asm b/tests/functional/coercion3.asm index b6aa0fdf3..5b287b87e 100644 --- a/tests/functional/coercion3.asm +++ b/tests/functional/coercion3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 04h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_c) - call PAPER + call core.PAPER ld a, (_c) ld l, a add a, a @@ -31,14 +31,14 @@ __MAIN_PROGRAM__: ld h, a add hl, hl ld a, l - call PAPER - call COPY_ATTR + call core.PAPER + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,6 +52,7 @@ __END_PROGRAM: #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -59,70 +60,75 @@ __END_PROGRAM: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 28 "coercion3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 29 "coercion3.bas" END diff --git a/tests/functional/const0.asm b/tests/functional/const0.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/const0.asm +++ b/tests/functional/const0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/const1.asm b/tests/functional/const1.asm index 3fc005cd9..96b6e435c 100644 --- a/tests/functional/const1.asm +++ b/tests/functional/const1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/const3.asm b/tests/functional/const3.asm index dff519818..309827161 100644 --- a/tests/functional/const3.asm +++ b/tests/functional/const3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _dgConnected: DEFW __LABEL0 _dgConnected.__DATA__.__PTR__: @@ -33,14 +33,14 @@ __LABEL0: DEFW 0001h DEFW 0002h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/const6.asm b/tests/functional/const6.asm index 479d574ff..5e4ca4118 100644 --- a/tests/functional/const6.asm +++ b/tests/functional/const6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _b - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -123,6 +123,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -152,6 +153,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -277,9 +279,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -287,37 +290,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -330,90 +334,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -483,94 +489,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -592,132 +600,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -742,5 +755,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 23 "const6.bas" END diff --git a/tests/functional/const7.asm b/tests/functional/const7.asm index 7fad5ab1d..1234eecd1 100644 --- a/tests/functional/const7.asm +++ b/tests/functional/const7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _x ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/const8.asm b/tests/functional/const8.asm index b1a4d4021..f80d57bea 100644 --- a/tests/functional/const8.asm +++ b/tests/functional/const8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 12345 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/const_expr.asm b/tests/functional/const_expr.asm index 652e5adb7..5227211c3 100644 --- a/tests/functional/const_expr.asm +++ b/tests/functional/const_expr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 6 ld (_f), a ld a, 4 @@ -121,9 +121,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/constrig.asm b/tests/functional/constrig.asm index 7395edaca..d88b256ca 100644 --- a/tests/functional/constrig.asm +++ b/tests/functional/constrig.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,71 +8,71 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 07Fh ld de, 099B3h ld bc, 0F5DBh ld hl, _a - call __STOREF + call core.__STOREF ld a, 080h ld de, 0BBEFh ld bc, 01EA0h ld hl, _a - call __STOREF + call core.__STOREF ld a, 07Fh ld de, 0C93Fh ld bc, 064B0h ld hl, _a - call __STOREF + call core.__STOREF ld a, 07Dh ld de, 0244Dh ld bc, 0B093h ld hl, _a - call __STOREF + call core.__STOREF ld a, 081h ld de, 03D3Ch ld bc, 06791h ld hl, _a - call __STOREF + call core.__STOREF ld a, 07Fh ld de, 03915h ld bc, 030D3h ld hl, _a - call __STOREF + call core.__STOREF ld a, 081h ld de, 05A20h ld bc, 07589h ld hl, _a - call __STOREF + call core.__STOREF ld a, 086h ld de, 07604h ld bc, 00939h ld hl, _a - call __STOREF + call core.__STOREF ld a, 081h ld de, 0776Fh ld bc, 08B50h ld hl, _a - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -83,30 +83,32 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 62 "constrig.bas" END diff --git a/tests/functional/cpeq16.asm b/tests/functional/cpeq16.asm index 0724c1711..c1a139391 100644 --- a/tests/functional/cpeq16.asm +++ b/tests/functional/cpeq16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_b) ld hl, (_a) + call core.__EQ16 or a - sbc hl, de - jp nz, __LABEL1 + jp z, __LABEL1 ld de, (_a) ld hl, (_a) add hl, de @@ -37,9 +37,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,12 +50,14 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/eq16.asm" + push namespace core __EQ16: ; Test if 16bit values HL == DE - ; Returns result in A: 0 = False, FF = True - xor a ; Reset carry flag - sbc hl, de - ret nz - inc a - ret + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace #line 27 "cpeq16.bas" END diff --git a/tests/functional/data1.asm b/tests/functional/data1.asm index f93f52b94..67a3b3b41 100644 --- a/tests/functional/data1.asm +++ b/tests/functional/data1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,40 +8,40 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 9 - call __READ + call core.__READ ld hl, _a - call __STOREF + call core.__STOREF __LABEL__1010: __LABEL__4500: ld hl, __DATA__1 - call __RESTORE + call core.__RESTORE __LABEL__5000: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -78,6 +78,7 @@ __DATA__END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -107,6 +108,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -233,9 +235,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -243,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -286,148 +290,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -438,91 +449,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -539,124 +554,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -664,18 +685,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -745,94 +767,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -844,6 +868,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1120,32 +1145,35 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 32 "data1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 33 "data1.bas" END diff --git a/tests/functional/declare0.asm b/tests/functional/declare0.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/declare0.asm +++ b/tests/functional/declare0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/def_func_inline_for_next.asm b/tests/functional/def_func_inline_for_next.asm index 66d9e05e8..67ecf51bd 100644 --- a/tests/functional/def_func_inline_for_next.asm +++ b/tests/functional/def_func_inline_for_next.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/def_func_inline_ok.asm b/tests/functional/def_func_inline_ok.asm index 84856f0ef..b32c5676c 100644 --- a/tests/functional/def_func_inline_ok.asm +++ b/tests/functional/def_func_inline_ok.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/defb.asm b/tests/functional/defb.asm index 27a3e28df..673e2ef6a 100644 --- a/tests/functional/defb.asm +++ b/tests/functional/defb.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "defb.bas" DEFB "Man(e;@ " #line 4 "defb.bas" ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/define_val.asm b/tests/functional/define_val.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/define_val.asm +++ b/tests/functional/define_val.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_arr_at_label0.asm b/tests/functional/dim_arr_at_label0.asm index d3b6cfc76..09b2ed5d3 100644 --- a/tests/functional/dim_arr_at_label0.asm +++ b/tests/functional/dim_arr_at_label0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a.__DATA__ EQU __LABEL__c _a: DEFW __LABEL0 @@ -26,15 +26,15 @@ _a.__DATA__.__PTR__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__c: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_arr_at_label1.asm b/tests/functional/dim_arr_at_label1.asm index bfab8d6c9..e36437237 100644 --- a/tests/functional/dim_arr_at_label1.asm +++ b/tests/functional/dim_arr_at_label1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a.__DATA__ EQU (__LABEL__c) + (1) _a: DEFW __LABEL0 @@ -26,15 +26,15 @@ _a.__DATA__.__PTR__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__c: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_arr_at_label2.asm b/tests/functional/dim_arr_at_label2.asm index d02c64fb8..c6c073f1d 100644 --- a/tests/functional/dim_arr_at_label2.asm +++ b/tests/functional/dim_arr_at_label2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _tile.__DATA__ EQU 16768 _tile: DEFW __LABEL0 @@ -26,14 +26,14 @@ _tile.__DATA__.__PTR__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_at_label0.asm b/tests/functional/dim_at_label0.asm index d7999af91..f095899c3 100644 --- a/tests/functional/dim_at_label0.asm +++ b/tests/functional/dim_at_label0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__somelabel: _x: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_at_label1.asm b/tests/functional/dim_at_label1.asm index 33861de85..e7fa8ad6d 100644 --- a/tests/functional/dim_at_label1.asm +++ b/tests/functional/dim_at_label1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x EQU (__LABEL__somelabel) + (1) -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__somelabel: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_at_label2.asm b/tests/functional/dim_at_label2.asm index 33861de85..e7fa8ad6d 100644 --- a/tests/functional/dim_at_label2.asm +++ b/tests/functional/dim_at_label2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x EQU (__LABEL__somelabel) + (1) -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__somelabel: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_at_label3.asm b/tests/functional/dim_at_label3.asm index d7999af91..f095899c3 100644 --- a/tests/functional/dim_at_label3.asm +++ b/tests/functional/dim_at_label3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__somelabel: _x: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_at_label8.asm b/tests/functional/dim_at_label8.asm index 448102c33..c25ae56c1 100644 --- a/tests/functional/dim_at_label8.asm +++ b/tests/functional/dim_at_label8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _p EQU 16768 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_const0.asm b/tests/functional/dim_const0.asm index 60cf97611..3f58fc4e6 100644 --- a/tests/functional/dim_const0.asm +++ b/tests/functional/dim_const0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFW __LABEL0 _c.__DATA__.__PTR__: @@ -28,14 +28,14 @@ _c.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dim_const_const.asm b/tests/functional/dim_const_const.asm index cf1321ea6..dc87b1caa 100644 --- a/tests/functional/dim_const_const.asm +++ b/tests/functional/dim_const_const.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _mobCoords: DEFW __LABEL0 _mobCoords.__DATA__.__PTR__: @@ -33,14 +33,14 @@ __LABEL0: DEFW 0001h DEFW 0002h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst.asm b/tests/functional/dimconst.asm index 2c5474f58..332ad79dd 100644 --- a/tests/functional/dimconst.asm +++ b/tests/functional/dimconst.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _Map: DEFB 00, 00 _MapPtr: DEFW (_Map) + (2) -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst2.asm b/tests/functional/dimconst2.asm index d2df17ee4..2daca1fe6 100644 --- a/tests/functional/dimconst2.asm +++ b/tests/functional/dimconst2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__Map: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst2c.asm b/tests/functional/dimconst2c.asm index 2a1e3e183..bf473fb3e 100644 --- a/tests/functional/dimconst2c.asm +++ b/tests/functional/dimconst2c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _Map: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_Map), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst2d.asm b/tests/functional/dimconst2d.asm index c8bb1974b..ca01ad16b 100644 --- a/tests/functional/dimconst2d.asm +++ b/tests/functional/dimconst2d.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _Map: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst2e.asm b/tests/functional/dimconst2e.asm index 7f7a35706..05537957a 100644 --- a/tests/functional/dimconst2e.asm +++ b/tests/functional/dimconst2e.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _Map: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_Map), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst3.asm b/tests/functional/dimconst3.asm index 3fe4943bd..7d88ae6f7 100644 --- a/tests/functional/dimconst3.asm +++ b/tests/functional/dimconst3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL__Map -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__Map: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst4.asm b/tests/functional/dimconst4.asm index 3e6387572..b3fdf1ceb 100644 --- a/tests/functional/dimconst4.asm +++ b/tests/functional/dimconst4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB (__LABEL__Map) & 0xFF -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__Map: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst4b.asm b/tests/functional/dimconst4b.asm index 3fe4943bd..7d88ae6f7 100644 --- a/tests/functional/dimconst4b.asm +++ b/tests/functional/dimconst4b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL__Map -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__Map: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst4c.asm b/tests/functional/dimconst4c.asm index d1fb901c5..49c3d26f6 100644 --- a/tests/functional/dimconst4c.asm +++ b/tests/functional/dimconst4c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW ((__LABEL__Map) & 0xFFFFFFFF) & 0xFFFF DEFW ((__LABEL__Map) & 0xFFFFFFFF) >> 16 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__Map: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst5.asm b/tests/functional/dimconst5.asm index 7cfb51336..ea39d5786 100644 --- a/tests/functional/dimconst5.asm +++ b/tests/functional/dimconst5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 0FEh -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst6.asm b/tests/functional/dimconst6.asm index 4f4508186..de06ed44b 100644 --- a/tests/functional/dimconst6.asm +++ b/tests/functional/dimconst6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _Map: DEFB 34h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dimconst7.asm b/tests/functional/dimconst7.asm index a16dbc93e..901b89088 100644 --- a/tests/functional/dimconst7.asm +++ b/tests/functional/dimconst7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW (_c.__DATA__ + 11) _c: @@ -45,14 +45,14 @@ __LABEL0: DEFW 0001h DEFW 0004h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/div32.asm b/tests/functional/div32.asm index ca413e90d..3d31b5662 100644 --- a/tests/functional/div32.asm +++ b/tests/functional/div32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __NEGF + call core.__NEGF push bc push de ld h, a @@ -35,9 +35,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,146 +50,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/negf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/negf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -206,22 +211,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/negf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -236,19 +243,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/negf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -258,12 +266,14 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __NEGF: ; A = -A - call __FPSTACK_PUSH - ; ------------- ROM NEGATE - rst 28h - defb 1Bh ; NEGF - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + ; ------------- ROM NEGATE + rst 28h + defb 1Bh ; NEGF + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 27 "div32.bas" END diff --git a/tests/functional/divf00.asm b/tests/functional/divf00.asm index f7b4ee0ec..e5f84e296 100644 --- a/tests/functional/divf00.asm +++ b/tests/functional/divf00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 80h DEFB 00h @@ -30,22 +30,22 @@ _b: DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _b + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 082h ld de, 00000h ld bc, 00000h - call __DIVF + call core.__DIVF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,12 +60,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -80,23 +81,25 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -126,6 +129,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/divf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -135,48 +139,51 @@ __STOP: ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __DIVF: ; Division - PROC - LOCAL __DIVBYZERO - LOCAL TMP, ERR_SP + PROC + LOCAL __DIVBYZERO + LOCAL TMP, ERR_SP TMP EQU 23629 ;(DEST) ERR_SP EQU 23613 - call __FPSTACK_PUSH2 - ld hl, (ERR_SP) - ld (TMP), hl - ld hl, __DIVBYZERO - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - ; ------------- ROM DIV - rst 28h - defb 01h ; EXCHANGE - defb 05h ; DIV - defb 38h; ; END CALC - pop hl - ld hl, (TMP) - ld (ERR_SP), hl - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ld hl, (ERR_SP) + ld (TMP), hl + ld hl, __DIVBYZERO + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl + ; ------------- ROM DIV + rst 28h + defb 01h ; EXCHANGE + defb 05h ; DIV + defb 38h; ; END CALC + pop hl + ld hl, (TMP) + ld (ERR_SP), hl + jp __FPSTACK_POP __DIVBYZERO: - ld hl, (TMP) - ld (ERR_SP), hl - ld a, ERROR_NumberTooBig - ld (ERR_NR), a - ; Returns 0 on DIV BY ZERO error - xor a - ld b, a - ld c, a - ld d, a - ld e, a - ret - ENDP + ld hl, (TMP) + ld (ERR_SP), hl + ld a, ERROR_NumberTooBig + ld (ERR_NR), a + ; Returns 0 on DIV BY ZERO error + xor a + ld b, a + ld c, a + ld d, a + ld e, a + ret + ENDP + pop namespace #line 25 "divf00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -197,32 +204,35 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 26 "divf00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 27 "divf00.bas" END diff --git a/tests/functional/divf01.asm b/tests/functional/divf01.asm index 49ccd195b..53c511c72 100644 --- a/tests/functional/divf01.asm +++ b/tests/functional/divf01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 80h DEFB 00h @@ -30,8 +30,8 @@ _b: DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) @@ -41,15 +41,15 @@ __MAIN_PROGRAM__: push hl ld h, 082h push hl - call __DIVF + call core.__DIVF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,12 +64,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -84,23 +85,25 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -130,6 +133,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/divf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -139,68 +143,72 @@ __STOP: ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __DIVF: ; Division - PROC - LOCAL __DIVBYZERO - LOCAL TMP, ERR_SP + PROC + LOCAL __DIVBYZERO + LOCAL TMP, ERR_SP TMP EQU 23629 ;(DEST) ERR_SP EQU 23613 - call __FPSTACK_PUSH2 - ld hl, (ERR_SP) - ld (TMP), hl - ld hl, __DIVBYZERO - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - ; ------------- ROM DIV - rst 28h - defb 01h ; EXCHANGE - defb 05h ; DIV - defb 38h; ; END CALC - pop hl - ld hl, (TMP) - ld (ERR_SP), hl - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ld hl, (ERR_SP) + ld (TMP), hl + ld hl, __DIVBYZERO + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl + ; ------------- ROM DIV + rst 28h + defb 01h ; EXCHANGE + defb 05h ; DIV + defb 38h; ; END CALC + pop hl + ld hl, (TMP) + ld (ERR_SP), hl + jp __FPSTACK_POP __DIVBYZERO: - ld hl, (TMP) - ld (ERR_SP), hl - ld a, ERROR_NumberTooBig - ld (ERR_NR), a - ; Returns 0 on DIV BY ZERO error - xor a - ld b, a - ld c, a - ld d, a - ld e, a - ret - ENDP + ld hl, (TMP) + ld (ERR_SP), hl + ld a, ERROR_NumberTooBig + ld (ERR_NR), a + ; Returns 0 on DIV BY ZERO error + xor a + ld b, a + ld c, a + ld d, a + ld e, a + ret + ENDP + pop namespace #line 29 "divf01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 30 "divf01.bas" END diff --git a/tests/functional/divf16.asm b/tests/functional/divf16.asm index 9fd3b23e2..ac8253427 100644 --- a/tests/functional/divf16.asm +++ b/tests/functional/divf16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld (_b), hl @@ -34,7 +34,7 @@ __MAIN_PROGRAM__: push hl ld de, 2 ld hl, 0 - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, (_a + 2) @@ -43,7 +43,7 @@ __MAIN_PROGRAM__: push hl ld de, 4 ld hl, 0 - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, (_a) @@ -52,7 +52,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, (_a) @@ -61,7 +61,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, (_a) @@ -70,7 +70,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, (_a) @@ -79,7 +79,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, (_a + 2) @@ -88,15 +88,15 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __DIVF16 + call core.__DIVF16 ld (_b), hl ld (_b + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -109,206 +109,212 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" + push namespace core __DIVF16: ; 16.16 Fixed point Division (signed) - ; DE.HL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - ex de, hl ; D'E'.H'L' Dividend + ; DE.HL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ex de, hl ; D'E'.H'L' Dividend __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with D'E'.H'L' - ex af, af' - xor d - ex af, af' ; Stores sign of the result for later - bit 7, d ; Negative? - call nz, __NEG32 - exx ; Now we have DE.HL => Dividend - ld b, 16 + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with D'E'.H'L' + ex af, af' + xor d + ex af, af' ; Stores sign of the result for later + bit 7, d ; Negative? + call nz, __NEG32 + exx ; Now we have DE.HL => Dividend + ld b, 16 __SHIFTALOOP: ; Tries to shift Dividend to the left - bit 7, d - jp nz, __SHIFTB - add hl, hl - ex de, hl - adc hl, hl - ex de, hl - djnz __SHIFTALOOP - jp __DOF16_DIVRDY + bit 7, d + jp nz, __SHIFTB + add hl, hl + ex de, hl + adc hl, hl + ex de, hl + djnz __SHIFTALOOP + jp __DOF16_DIVRDY __SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right - ld a, b - exx - ld b, a - ; Divisor is in DEHL + ld a, b + exx + ld b, a + ; Divisor is in DEHL __SHIFTBLOOP: - bit 1, l - jp nz, __DOF16_DIVIDE - sra d - rr e - rr h - rr l - djnz __SHIFTBLOOP + bit 1, l + jp nz, __DOF16_DIVIDE + sra d + rr e + rr h + rr l + djnz __SHIFTBLOOP __DOF16_DIVIDE: - ld a, b - exx - ld b, a + ld a, b + exx + ld b, a __DOF16_DIVRDY: - exx - ex de, hl - push bc - call __DIVU32START - pop bc - xor a - or b - jp z, __ENDF16DIV + exx + ex de, hl + push bc + call __DIVU32START + pop bc + xor a + or b + jp z, __ENDF16DIV __SHIFTCLOOP: - add hl, hl ; Shift DECIMAL PART << 1 - ex de, hl - adc hl, hl ; Shift INTEGER PART << 1 Plus Carry - ex de, hl - djnz __SHIFTCLOOP + add hl, hl ; Shift DECIMAL PART << 1 + ex de, hl + adc hl, hl ; Shift INTEGER PART << 1 Plus Carry + ex de, hl + djnz __SHIFTCLOOP __ENDF16DIV: ; Put the sign on the result - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there + pop namespace #line 84 "divf16.bas" END diff --git a/tests/functional/divf16a.asm b/tests/functional/divf16a.asm index 4e895ac7e..bf5f95817 100644 --- a/tests/functional/divf16a.asm +++ b/tests/functional/divf16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,40 +8,40 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld hl, (_a) ld de, (_a + 2) - call __DIVF16 + call core.__DIVF16 push de push hl ld hl, (_a) ld de, (_a + 2) - call __DIVF16 + call core.__DIVF16 ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,206 +54,212 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" + push namespace core __DIVF16: ; 16.16 Fixed point Division (signed) - ; DE.HL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - ex de, hl ; D'E'.H'L' Dividend + ; DE.HL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ex de, hl ; D'E'.H'L' Dividend __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with D'E'.H'L' - ex af, af' - xor d - ex af, af' ; Stores sign of the result for later - bit 7, d ; Negative? - call nz, __NEG32 - exx ; Now we have DE.HL => Dividend - ld b, 16 + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with D'E'.H'L' + ex af, af' + xor d + ex af, af' ; Stores sign of the result for later + bit 7, d ; Negative? + call nz, __NEG32 + exx ; Now we have DE.HL => Dividend + ld b, 16 __SHIFTALOOP: ; Tries to shift Dividend to the left - bit 7, d - jp nz, __SHIFTB - add hl, hl - ex de, hl - adc hl, hl - ex de, hl - djnz __SHIFTALOOP - jp __DOF16_DIVRDY + bit 7, d + jp nz, __SHIFTB + add hl, hl + ex de, hl + adc hl, hl + ex de, hl + djnz __SHIFTALOOP + jp __DOF16_DIVRDY __SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right - ld a, b - exx - ld b, a - ; Divisor is in DEHL + ld a, b + exx + ld b, a + ; Divisor is in DEHL __SHIFTBLOOP: - bit 1, l - jp nz, __DOF16_DIVIDE - sra d - rr e - rr h - rr l - djnz __SHIFTBLOOP + bit 1, l + jp nz, __DOF16_DIVIDE + sra d + rr e + rr h + rr l + djnz __SHIFTBLOOP __DOF16_DIVIDE: - ld a, b - exx - ld b, a + ld a, b + exx + ld b, a __DOF16_DIVRDY: - exx - ex de, hl - push bc - call __DIVU32START - pop bc - xor a - or b - jp z, __ENDF16DIV + exx + ex de, hl + push bc + call __DIVU32START + pop bc + xor a + or b + jp z, __ENDF16DIV __SHIFTCLOOP: - add hl, hl ; Shift DECIMAL PART << 1 - ex de, hl - adc hl, hl ; Shift INTEGER PART << 1 Plus Carry - ex de, hl - djnz __SHIFTCLOOP + add hl, hl ; Shift DECIMAL PART << 1 + ex de, hl + adc hl, hl ; Shift INTEGER PART << 1 Plus Carry + ex de, hl + djnz __SHIFTCLOOP __ENDF16DIV: ; Put the sign on the result - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there + pop namespace #line 31 "divf16a.bas" END diff --git a/tests/functional/divf16b.asm b/tests/functional/divf16b.asm index b37b515b3..fd16e3468 100644 --- a/tests/functional/divf16b.asm +++ b/tests/functional/divf16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld hl, (_a) ld de, (_a + 2) - call __DIVF16 + call core.__DIVF16 push de push hl ld hl, (_a + 2) @@ -37,21 +37,21 @@ __MAIN_PROGRAM__: push hl ld de, 2 ld hl, 0 - call __DIVF16 + call core.__DIVF16 push de push hl ld hl, (_a) ld de, (_a + 2) - call __DIVF16 - call __DIVF16 + call core.__DIVF16 + call core.__DIVF16 ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,206 +64,212 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" + push namespace core __DIVF16: ; 16.16 Fixed point Division (signed) - ; DE.HL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - ex de, hl ; D'E'.H'L' Dividend + ; DE.HL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ex de, hl ; D'E'.H'L' Dividend __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with D'E'.H'L' - ex af, af' - xor d - ex af, af' ; Stores sign of the result for later - bit 7, d ; Negative? - call nz, __NEG32 - exx ; Now we have DE.HL => Dividend - ld b, 16 + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with D'E'.H'L' + ex af, af' + xor d + ex af, af' ; Stores sign of the result for later + bit 7, d ; Negative? + call nz, __NEG32 + exx ; Now we have DE.HL => Dividend + ld b, 16 __SHIFTALOOP: ; Tries to shift Dividend to the left - bit 7, d - jp nz, __SHIFTB - add hl, hl - ex de, hl - adc hl, hl - ex de, hl - djnz __SHIFTALOOP - jp __DOF16_DIVRDY + bit 7, d + jp nz, __SHIFTB + add hl, hl + ex de, hl + adc hl, hl + ex de, hl + djnz __SHIFTALOOP + jp __DOF16_DIVRDY __SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right - ld a, b - exx - ld b, a - ; Divisor is in DEHL + ld a, b + exx + ld b, a + ; Divisor is in DEHL __SHIFTBLOOP: - bit 1, l - jp nz, __DOF16_DIVIDE - sra d - rr e - rr h - rr l - djnz __SHIFTBLOOP + bit 1, l + jp nz, __DOF16_DIVIDE + sra d + rr e + rr h + rr l + djnz __SHIFTBLOOP __DOF16_DIVIDE: - ld a, b - exx - ld b, a + ld a, b + exx + ld b, a __DOF16_DIVRDY: - exx - ex de, hl - push bc - call __DIVU32START - pop bc - xor a - or b - jp z, __ENDF16DIV + exx + ex de, hl + push bc + call __DIVU32START + pop bc + xor a + or b + jp z, __ENDF16DIV __SHIFTCLOOP: - add hl, hl ; Shift DECIMAL PART << 1 - ex de, hl - adc hl, hl ; Shift INTEGER PART << 1 Plus Carry - ex de, hl - djnz __SHIFTCLOOP + add hl, hl ; Shift DECIMAL PART << 1 + ex de, hl + adc hl, hl ; Shift INTEGER PART << 1 Plus Carry + ex de, hl + djnz __SHIFTCLOOP __ENDF16DIV: ; Put the sign on the result - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there + pop namespace #line 41 "divf16b.bas" END diff --git a/tests/functional/divf16c.asm b/tests/functional/divf16c.asm index c312a6605..8dc335e0d 100644 --- a/tests/functional/divf16c.asm +++ b/tests/functional/divf16c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __DIVF16 + call core.__SWAP32 + call core.__DIVF16 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __DIVF16 + call core.__DIVF16 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __DIVF16 + call core.__DIVF16 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -66,7 +66,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __DIVF16 + call core.__DIVF16 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -75,15 +75,15 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __DIVF16 + call core.__DIVF16 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -96,213 +96,220 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" + push namespace core __DIVF16: ; 16.16 Fixed point Division (signed) - ; DE.HL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - ex de, hl ; D'E'.H'L' Dividend + ; DE.HL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ex de, hl ; D'E'.H'L' Dividend __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with D'E'.H'L' - ex af, af' - xor d - ex af, af' ; Stores sign of the result for later - bit 7, d ; Negative? - call nz, __NEG32 - exx ; Now we have DE.HL => Dividend - ld b, 16 + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with D'E'.H'L' + ex af, af' + xor d + ex af, af' ; Stores sign of the result for later + bit 7, d ; Negative? + call nz, __NEG32 + exx ; Now we have DE.HL => Dividend + ld b, 16 __SHIFTALOOP: ; Tries to shift Dividend to the left - bit 7, d - jp nz, __SHIFTB - add hl, hl - ex de, hl - adc hl, hl - ex de, hl - djnz __SHIFTALOOP - jp __DOF16_DIVRDY + bit 7, d + jp nz, __SHIFTB + add hl, hl + ex de, hl + adc hl, hl + ex de, hl + djnz __SHIFTALOOP + jp __DOF16_DIVRDY __SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right - ld a, b - exx - ld b, a - ; Divisor is in DEHL + ld a, b + exx + ld b, a + ; Divisor is in DEHL __SHIFTBLOOP: - bit 1, l - jp nz, __DOF16_DIVIDE - sra d - rr e - rr h - rr l - djnz __SHIFTBLOOP + bit 1, l + jp nz, __DOF16_DIVIDE + sra d + rr e + rr h + rr l + djnz __SHIFTBLOOP __DOF16_DIVIDE: - ld a, b - exx - ld b, a + ld a, b + exx + ld b, a __DOF16_DIVRDY: - exx - ex de, hl - push bc - call __DIVU32START - pop bc - xor a - or b - jp z, __ENDF16DIV + exx + ex de, hl + push bc + call __DIVU32START + pop bc + xor a + or b + jp z, __ENDF16DIV __SHIFTCLOOP: - add hl, hl ; Shift DECIMAL PART << 1 - ex de, hl - adc hl, hl ; Shift INTEGER PART << 1 Plus Carry - ex de, hl - djnz __SHIFTCLOOP + add hl, hl ; Shift DECIMAL PART << 1 + ex de, hl + adc hl, hl ; Shift INTEGER PART << 1 Plus Carry + ex de, hl + djnz __SHIFTCLOOP __ENDF16DIV: ; Put the sign on the result - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there + pop namespace #line 63 "divf16c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -312,6 +319,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 64 "divf16c.bas" END diff --git a/tests/functional/divi16a.asm b/tests/functional/divi16a.asm index 1ae1c701b..cb5931ae3 100644 --- a/tests/functional/divi16a.asm +++ b/tests/functional/divi16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,23 +48,26 @@ __END_PROGRAM: ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -87,49 +90,50 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 23 "divi16a.bas" END diff --git a/tests/functional/divi16b.asm b/tests/functional/divi16b.asm index 5218090de..dae90e9d9 100644 --- a/tests/functional/divi16b.asm +++ b/tests/functional/divi16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a) - call __DIVU16 + call core.__DIVU16 push hl ld hl, (_a) srl h rr l ld de, (_a) - call __DIVU16 + call core.__DIVU16 ex de, hl pop hl - call __DIVU16 + call core.__DIVU16 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,23 +55,26 @@ __END_PROGRAM: ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -94,49 +97,50 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 30 "divi16b.bas" END diff --git a/tests/functional/divi32c.asm b/tests/functional/divi32c.asm index 119b722e5..a9691c291 100644 --- a/tests/functional/divi32c.asm +++ b/tests/functional/divi32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,15 +30,15 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __DIVI32 + call core.__DIVI32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -47,8 +47,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __DIVI32 + call core.__SWAP32 + call core.__DIVI32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,8 +57,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __DIVI32 + call core.__SWAP32 + call core.__DIVI32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -67,8 +67,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __DIVI32 + call core.__SWAP32 + call core.__DIVI32 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -77,16 +77,16 @@ __MAIN_PROGRAM__: push bc ld bc, 2 push bc - call __SWAP32 - call __DIVI32 + call core.__SWAP32 + call core.__DIVI32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -98,145 +98,150 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 66 "divi32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -246,6 +251,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 67 "divi32c.bas" END diff --git a/tests/functional/divi8.asm b/tests/functional/divi8.asm index 19c749f2e..e07c73e04 100644 --- a/tests/functional/divi8.asm +++ b/tests/functional/divi8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -31,32 +31,32 @@ __MAIN_PROGRAM__: ld (_b), a ld a, (_a) ld h, 4 - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_b), a xor a ld (_b), a ld a, 1 ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_b), a ld a, 2 ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_b), a ld a, 4 ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_b), a ld a, (_a) ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -67,67 +67,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 44 "divi8.bas" END diff --git a/tests/functional/divi8a.asm b/tests/functional/divi8a.asm index 3d1259fe1..f43cd6fa1 100644 --- a/tests/functional/divi8a.asm +++ b/tests/functional/divi8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,67 +44,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 23 "divi8a.bas" END diff --git a/tests/functional/divi8b.asm b/tests/functional/divi8b.asm index 8b20c34c9..eb778eacd 100644 --- a/tests/functional/divi8b.asm +++ b/tests/functional/divi8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST push af ld a, (_a) sra a ld hl, (_a - 1) - call __DIVI8_FAST + call core.__DIVI8_FAST ld h, a pop af - call __DIVI8_FAST + call core.__DIVI8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,67 +50,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 29 "divi8b.bas" END diff --git a/tests/functional/divu16.asm b/tests/functional/divu16.asm index e737bccc4..e03ad6cdc 100644 --- a/tests/functional/divu16.asm +++ b/tests/functional/divu16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld (_b), hl ld hl, (_a) @@ -32,32 +32,32 @@ __MAIN_PROGRAM__: ld (_b), hl ld hl, (_a) ld de, 4 - call __DIVU16 + call core.__DIVU16 ld (_b), hl ld hl, 0 ld (_b), hl ld hl, 1 ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld (_b), hl ld hl, 2 ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld (_b), hl ld hl, 4 ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld (_b), hl ld hl, (_a) ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -72,23 +72,26 @@ __END_PROGRAM: ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -111,49 +114,50 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 45 "divu16.bas" END diff --git a/tests/functional/divu16a.asm b/tests/functional/divu16a.asm index 5655f4543..402e206bd 100644 --- a/tests/functional/divu16a.asm +++ b/tests/functional/divu16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld de, (_a) - call __DIVU16 + call core.__DIVU16 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,23 +48,26 @@ __END_PROGRAM: ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -87,49 +90,50 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 23 "divu16a.bas" END diff --git a/tests/functional/divu16b.asm b/tests/functional/divu16b.asm index b7b15e169..58ef52be5 100644 --- a/tests/functional/divu16b.asm +++ b/tests/functional/divu16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a) - call __DIVU16 + call core.__DIVU16 push hl ld hl, (_a) srl h rr l ld de, (_a) - call __DIVU16 + call core.__DIVU16 ex de, hl pop hl - call __DIVU16 + call core.__DIVU16 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,23 +55,26 @@ __END_PROGRAM: ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -94,49 +97,50 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 30 "divu16b.bas" END diff --git a/tests/functional/divu32c.asm b/tests/functional/divu32c.asm index 5f6646863..459d5269c 100644 --- a/tests/functional/divu32c.asm +++ b/tests/functional/divu32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,15 +30,15 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __DIVU32 + call core.__DIVU32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -47,8 +47,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __DIVU32 + call core.__SWAP32 + call core.__DIVU32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,8 +57,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __DIVU32 + call core.__SWAP32 + call core.__DIVU32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -67,8 +67,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __DIVU32 + call core.__SWAP32 + call core.__DIVU32 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -77,16 +77,16 @@ __MAIN_PROGRAM__: push bc ld bc, 2 push bc - call __SWAP32 - call __DIVU32 + call core.__SWAP32 + call core.__DIVU32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -98,145 +98,150 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 66 "divu32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -246,6 +251,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 67 "divu32c.bas" END diff --git a/tests/functional/divu8.asm b/tests/functional/divu8.asm index 0fcd32855..6d895311a 100644 --- a/tests/functional/divu8.asm +++ b/tests/functional/divu8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -31,32 +31,32 @@ __MAIN_PROGRAM__: ld (_b), a ld a, (_a) ld h, 4 - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_b), a xor a ld (_b), a ld a, 1 ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_b), a ld a, 2 ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_b), a ld a, 4 ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_b), a ld a, (_a) ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -67,67 +67,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 44 "divu8.bas" END diff --git a/tests/functional/divu8a.asm b/tests/functional/divu8a.asm index 4e2db589a..2c1118308 100644 --- a/tests/functional/divu8a.asm +++ b/tests/functional/divu8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,67 +44,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 23 "divu8a.bas" END diff --git a/tests/functional/divu8b.asm b/tests/functional/divu8b.asm index daa11cd69..06eb67d7b 100644 --- a/tests/functional/divu8b.asm +++ b/tests/functional/divu8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST push af ld a, (_a) srl a ld hl, (_a - 1) - call __DIVU8_FAST + call core.__DIVU8_FAST ld h, a pop af - call __DIVU8_FAST + call core.__DIVU8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,67 +50,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 29 "divu8b.bas" END diff --git a/tests/functional/dollar.asm b/tests/functional/dollar.asm index f2544e100..f0d2e0c7e 100644 --- a/tests/functional/dollar.asm +++ b/tests/functional/dollar.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "dollar.bas" jr $+2 #line 6 "dollar.bas" ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/doloop.asm b/tests/functional/doloop.asm index 763987ca3..754635da6 100644 --- a/tests/functional/doloop.asm +++ b/tests/functional/doloop.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL0: __LABEL__20: @@ -46,9 +46,9 @@ __LABEL7: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/doloop1.asm b/tests/functional/doloop1.asm index f482cc24b..c1a95978d 100644 --- a/tests/functional/doloop1.asm +++ b/tests/functional/doloop1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: jp __LABEL0 __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/doloop2.asm b/tests/functional/doloop2.asm index 9df85ca84..1b74e9944 100644 --- a/tests/functional/doloop2.asm +++ b/tests/functional/doloop2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL0: __LABEL__20: @@ -44,9 +44,9 @@ __LABEL7: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/doloop3.asm b/tests/functional/doloop3.asm index 069093be2..8e1e3b0b7 100644 --- a/tests/functional/doloop3.asm +++ b/tests/functional/doloop3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL0: __LABEL__20: @@ -45,9 +45,9 @@ __LABEL7: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/doloop4.asm b/tests/functional/doloop4.asm index 31b64f64c..6b1af5ed2 100644 --- a/tests/functional/doloop4.asm +++ b/tests/functional/doloop4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL0: __LABEL__20: diff --git a/tests/functional/dountil1.asm b/tests/functional/dountil1.asm index 0667df6e3..cd4121a11 100644 --- a/tests/functional/dountil1.asm +++ b/tests/functional/dountil1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: __LABEL2: jp __LABEL0 @@ -27,9 +27,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dountilempty.asm b/tests/functional/dountilempty.asm index 7498c495d..b0f25b041 100644 --- a/tests/functional/dountilempty.asm +++ b/tests/functional/dountilempty.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: jp __LABEL2 __LABEL0: __LABEL2: ld a, 10 ld hl, (_i - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,8 +48,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -67,6 +68,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 26 "dountilempty.bas" END diff --git a/tests/functional/dountilsplitted.asm b/tests/functional/dountilsplitted.asm index 04dda6e7f..03f3b420d 100644 --- a/tests/functional/dountilsplitted.asm +++ b/tests/functional/dountilsplitted.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00, 00, 00, 00 _M: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: jp __LABEL2 __LABEL0: xor a ld (_M), a __LABEL2: ld hl, _i + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp z, __LABEL0 __LABEL1: @@ -44,20 +44,20 @@ __LABEL3: ld (_M), a __LABEL5: ld hl, _i + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp z, __LABEL3 __LABEL4: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -70,146 +70,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -226,22 +231,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -256,19 +263,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -278,21 +286,24 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __EQF: ; A = B - call __FPSTACK_PUSH2 - ; ------------- ROM NOS-EQL - ld b, 0Eh ; For comparison operators, OP must be in B also - rst 28h - defb 0Eh - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 45 "dountilsplitted.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -313,5 +324,6 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 46 "dountilsplitted.bas" END diff --git a/tests/functional/dowhile1.asm b/tests/functional/dowhile1.asm index 0667df6e3..cd4121a11 100644 --- a/tests/functional/dowhile1.asm +++ b/tests/functional/dowhile1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: __LABEL2: jp __LABEL0 @@ -27,9 +27,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/dowhileempty.asm b/tests/functional/dowhileempty.asm index d99f2825a..9a8e3a09d 100644 --- a/tests/functional/dowhileempty.asm +++ b/tests/functional/dowhileempty.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: jp __LABEL2 __LABEL0: __LABEL2: ld h, 10 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL0 __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,8 +48,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -67,6 +68,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 26 "dowhileempty.bas" END diff --git a/tests/functional/dowhilesplitted.asm b/tests/functional/dowhilesplitted.asm index 9fc90bc8c..523fd7a41 100644 --- a/tests/functional/dowhilesplitted.asm +++ b/tests/functional/dowhilesplitted.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00, 00, 00, 00 _M: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: jp __LABEL2 __LABEL0: xor a ld (_M), a __LABEL2: ld hl, _i + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp nz, __LABEL0 __LABEL1: @@ -44,20 +44,20 @@ __LABEL3: ld (_M), a __LABEL5: ld hl, _i + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp nz, __LABEL3 __LABEL4: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -70,146 +70,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -226,22 +231,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -256,19 +263,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -278,21 +286,24 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __EQF: ; A = B - call __FPSTACK_PUSH2 - ; ------------- ROM NOS-EQL - ld b, 0Eh ; For comparison operators, OP must be in B also - rst 28h - defb 0Eh - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 45 "dowhilesplitted.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -313,5 +324,6 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 46 "dowhilesplitted.bas" END diff --git a/tests/functional/draw.asm b/tests/functional/draw.asm index e40620e6f..b70edd886 100644 --- a/tests/functional/draw.asm +++ b/tests/functional/draw.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,56 +8,56 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 11 push hl ld hl, 22 - call DRAW + call core.DRAW ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld hl, 22 - call DRAW + call core.DRAW ld hl, 11 push hl ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG - call DRAW + call core.__FTOU32REG + call core.DRAW ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG - call DRAW + call core.__FTOU32REG + call core.DRAW ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,6 +76,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -105,97 +106,105 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -203,7 +212,9 @@ __CLS_SCR: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -258,6 +269,7 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelDown.asm" ; @@ -274,32 +286,34 @@ SET_PIXEL_ADDR_ATTR: ; Carry'= moved off current cell (needs ATTR update) ; HL = moves one pixel down ; used : AF, HL + push namespace core SP.PixelDown: - inc h - ld a,h - and $07 - ret nz - ex af, af' ; Sets carry on F' - scf ; which flags ATTR must be updated - ex af, af' - ld a,h - sub $08 - ld h,a - ld a,l - add a,$20 - ld l,a - ret nc - ld a,h - add a,$08 - ld h,a + inc h + ld a,h + and $07 + ret nz + ex af, af' ; Sets carry on F' + scf ; which flags ATTR must be updated + ex af, af' + ld a,h + sub $08 + ld h,a + ld a,l + add a,$20 + ld l,a + ret nc + ld a,h + add a,$08 + ld h,a ;IF DISP_HIRES ; and $18 ; cp $18 ;ELSE - cp $58 + cp $58 ;ENDIF - ccf - ret + ccf + ret + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelUp.asm" ; @@ -315,32 +329,34 @@ SP.PixelDown: ; exit : Carry = moved off screen ; HL = moves one pixel up ; used : AF, HL + push namespace core SP.PixelUp: - ld a,h - dec h - and $07 - ret nz - ex af, af' - scf - ex af, af' - ld a,$08 - add a,h - ld h,a - ld a,l - sub $20 - ld l,a - ret nc - ld a,h - sub $08 - ld h,a + ld a,h + dec h + and $07 + ret nz + ex af, af' + scf + ex af, af' + ld a,$08 + add a,h + ld h,a + ld a,l + sub $20 + ld l,a + ret nc + ld a,h + sub $08 + ld h,a ;IF DISP_HIRES ; and $18 ; cp $18 ; ccf ;ELSE - cp $40 + cp $40 ;ENDIF - ret + ret + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelLeft.asm" ; @@ -359,6 +375,7 @@ SP.PixelUp: ; HL = moves one character left, if needed ; A = Bit Set with new pixel pos. ; used : AF, HL + push namespace core SP.PixelLeft: rlca ; Sets new pixel bit 1 to the right ret nc @@ -370,6 +387,7 @@ SP.PixelLeft: ccf ld a, 1 ret + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelRight.asm" ; @@ -388,6 +406,7 @@ SP.PixelLeft: ; HL = moves one character left, if needed ; A = Bit Set with new pixel pos. ; used : AF, HL + push namespace core SP.PixelRight: rrca ; Sets new pixel bit 1 to the right ret nc @@ -399,8 +418,10 @@ SP.PixelRight: ccf ld a, 80h ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" ;; DRAW PROCEDURE + push namespace core PROC LOCAL __DRAW1 LOCAL __DRAW2 @@ -481,10 +502,10 @@ __PIXEL_MASK: ld b, d ; Restores B' from D' pop de ; D'E' = y2, x2 exx ; At this point: D'E' = y2,x2 coords - ; B'C' = y1, y1 coords + ; B'C' = y1, y1 coords ex af, af' ; Saves A reg for later - ; A' = Pixel mask - ; H'L' = Screen Address of pixel + ; A' = Pixel mask + ; H'L' = Screen Address of pixel ld bc, (COORDS) ; B,C = y1, x1 ld a, e sub c ; dx = X2 - X1 @@ -637,7 +658,7 @@ __PLOTINVERSE: nop ; Replace with CPL if INVERSE 1 __PLOTOVER: or (hl) ; Replace with XOR (hl) if OVER 1 AND INVERSE 0 - ; Replace with AND (hl) if INVERSE 1 + ; Replace with AND (hl) if INVERSE 1 ld (hl), a ex af, af' ; Recovers flag. If Carry set => update ATTR ld a, e ; Recovers A reg @@ -656,80 +677,84 @@ __FASTPLOTEND: ld a, e ret ENDP + pop namespace #line 45 "draw.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -746,10 +771,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 46 "draw.bas" END diff --git a/tests/functional/draw3.asm b/tests/functional/draw3.asm index 0bdc4cb17..4474f0d05 100644 --- a/tests/functional/draw3.asm +++ b/tests/functional/draw3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 _c: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 11 push hl ld hl, 22 @@ -33,63 +33,63 @@ __MAIN_PROGRAM__: ld a, 086h ld de, 00004h ld bc, 00000h - call DRAW3 + call core.DRAW3 ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld hl, 22 push hl ld a, 086h ld de, 00004h ld bc, 00000h - call DRAW3 + call core.DRAW3 ld hl, 11 push hl ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, 086h ld de, 00004h ld bc, 00000h - call DRAW3 + call core.DRAW3 ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, 086h ld de, 00004h ld bc, 00000h - call DRAW3 + call core.DRAW3 ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, (_c) ld de, (_c + 1) ld bc, (_c + 3) - call DRAW3 + call core.DRAW3 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -110,6 +110,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -139,6 +140,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/draw3.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" ; MIXED __FASTCAL__ / __CALLE__ PLOT Function @@ -148,93 +150,100 @@ __STOP: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -242,7 +251,9 @@ __CLS_SCR: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -297,29 +308,31 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + push namespace core PLOT: - PROC - LOCAL PLOT_SUB - LOCAL PIXEL_ADDR - LOCAL COORDS - LOCAL __PLOT_ERR + PROC + LOCAL PLOT_SUB + LOCAL PIXEL_ADDR + LOCAL COORDS + LOCAL __PLOT_ERR LOCAL P_FLAG LOCAL __PLOT_OVER1 P_FLAG EQU 23697 - pop hl - ex (sp), hl ; Callee - ld b, a - ld c, h -#line 35 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 41 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" - ld a, 191 - cp b - jr c, __PLOT_ERR ; jr is faster here (#1) + pop hl + ex (sp), hl ; Callee + ld b, a + ld c, h +#line 37 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 43 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + ld a, 191 + cp b + jr c, __PLOT_ERR ; jr is faster here (#1) __PLOT: ; __FASTCALL__ entry (b, c) = pixel coords (y, x) - ld (COORDS), bc ; Saves current point - ld a, 191 ; Max y coord - call PIXEL_ADDR + ld (COORDS), bc ; Saves current point + ld a, 191 ; Max y coord + call PIXEL_ADDR res 6, h ; Starts from 0 ld bc, (SCREEN_ADDR) add hl, bc ; Now current offset @@ -351,18 +364,20 @@ __PLOT_ERR: PLOT_SUB EQU 22ECh PIXEL_ADDR EQU 22ACh COORDS EQU 5C7Dh - ENDP + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/draw3.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -377,19 +392,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/draw3.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" ; DRAW using bresenhams algorithm and screen positioning @@ -412,32 +428,34 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; Carry'= moved off current cell (needs ATTR update) ; HL = moves one pixel down ; used : AF, HL + push namespace core SP.PixelDown: - inc h - ld a,h - and $07 - ret nz - ex af, af' ; Sets carry on F' - scf ; which flags ATTR must be updated - ex af, af' - ld a,h - sub $08 - ld h,a - ld a,l - add a,$20 - ld l,a - ret nc - ld a,h - add a,$08 - ld h,a + inc h + ld a,h + and $07 + ret nz + ex af, af' ; Sets carry on F' + scf ; which flags ATTR must be updated + ex af, af' + ld a,h + sub $08 + ld h,a + ld a,l + add a,$20 + ld l,a + ret nc + ld a,h + add a,$08 + ld h,a ;IF DISP_HIRES ; and $18 ; cp $18 ;ELSE - cp $58 + cp $58 ;ENDIF - ccf - ret + ccf + ret + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelUp.asm" ; @@ -453,32 +471,34 @@ SP.PixelDown: ; exit : Carry = moved off screen ; HL = moves one pixel up ; used : AF, HL + push namespace core SP.PixelUp: - ld a,h - dec h - and $07 - ret nz - ex af, af' - scf - ex af, af' - ld a,$08 - add a,h - ld h,a - ld a,l - sub $20 - ld l,a - ret nc - ld a,h - sub $08 - ld h,a + ld a,h + dec h + and $07 + ret nz + ex af, af' + scf + ex af, af' + ld a,$08 + add a,h + ld h,a + ld a,l + sub $20 + ld l,a + ret nc + ld a,h + sub $08 + ld h,a ;IF DISP_HIRES ; and $18 ; cp $18 ; ccf ;ELSE - cp $40 + cp $40 ;ENDIF - ret + ret + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelLeft.asm" ; @@ -497,6 +517,7 @@ SP.PixelUp: ; HL = moves one character left, if needed ; A = Bit Set with new pixel pos. ; used : AF, HL + push namespace core SP.PixelLeft: rlca ; Sets new pixel bit 1 to the right ret nc @@ -508,6 +529,7 @@ SP.PixelLeft: ccf ld a, 1 ret + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelRight.asm" ; @@ -526,6 +548,7 @@ SP.PixelLeft: ; HL = moves one character left, if needed ; A = Bit Set with new pixel pos. ; used : AF, HL + push namespace core SP.PixelRight: rrca ; Sets new pixel bit 1 to the right ret nc @@ -537,8 +560,10 @@ SP.PixelRight: ccf ld a, 80h ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" ;; DRAW PROCEDURE + push namespace core PROC LOCAL __DRAW1 LOCAL __DRAW2 @@ -619,10 +644,10 @@ __PIXEL_MASK: ld b, d ; Restores B' from D' pop de ; D'E' = y2, x2 exx ; At this point: D'E' = y2,x2 coords - ; B'C' = y1, y1 coords + ; B'C' = y1, y1 coords ex af, af' ; Saves A reg for later - ; A' = Pixel mask - ; H'L' = Screen Address of pixel + ; A' = Pixel mask + ; H'L' = Screen Address of pixel ld bc, (COORDS) ; B,C = y1, x1 ld a, e sub c ; dx = X2 - X1 @@ -775,7 +800,7 @@ __PLOTINVERSE: nop ; Replace with CPL if INVERSE 1 __PLOTOVER: or (hl) ; Replace with XOR (hl) if OVER 1 AND INVERSE 0 - ; Replace with AND (hl) if INVERSE 1 + ; Replace with AND (hl) if INVERSE 1 ld (hl), a ex af, af' ; Recovers flag. If Carry set => update ATTR ld a, e ; Recovers A reg @@ -794,60 +819,62 @@ __FASTPLOTEND: ld a, e ret ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/draw3.asm" ; Ripped from the ZX Spectrum ROM + push namespace core DRAW3: - PROC - LOCAL STACK_TO_BC - LOCAL STACK_TO_A - LOCAL COORDS - LOCAL L2477 - LOCAL L2420 - LOCAL L2439 - LOCAL L245F - LOCAL L23C1 - LOCAL L2D28 - LOCAL SUM_C, SUM_B + PROC + LOCAL STACK_TO_BC + LOCAL STACK_TO_A + LOCAL COORDS + LOCAL L2477 + LOCAL L2420 + LOCAL L2439 + LOCAL L245F + LOCAL L23C1 + LOCAL L2D28 + LOCAL SUM_C, SUM_B L2D28 EQU 02D28h COORDS EQU 5C7Dh STACK_TO_BC EQU 2307h STACK_TO_A EQU 2314h - exx - ex af, af' ;; Preserves ARC - pop hl - pop de - ex (sp), hl ;; CALLEE - push de - call __FPSTACK_I16 ;; X Offset - pop hl - call __FPSTACK_I16 ;; Y Offset - exx - ex af, af' - call __FPSTACK_PUSH ;; R Arc + exx + ex af, af' ;; Preserves ARC + pop hl + pop de + ex (sp), hl ;; CALLEE + push de + call __FPSTACK_I16 ;; X Offset + pop hl + call __FPSTACK_I16 ;; Y Offset + exx + ex af, af' + call __FPSTACK_PUSH ;; R Arc ; Now enter the calculator and store the complete rotation angle in mem-5 - RST 28H ;; FP-CALC x, y, A. - DEFB $C5 ;;st-mem-5 x, y, A. + RST 28H ;; FP-CALC x, y, A. + DEFB $C5 ;;st-mem-5 x, y, A. ; Test the angle for the special case of 360 degrees. - DEFB $A2 ;;stk-half x, y, A, 1/2. - DEFB $04 ;;multiply x, y, A/2. - DEFB $1F ;;sin x, y, sin(A/2). - DEFB $31 ;;duplicate x, y, sin(A/2),sin(A/2) - DEFB $30 ;;not x, y, sin(A/2), (0/1). - DEFB $30 ;;not x, y, sin(A/2), (1/0). - DEFB $00 ;;jump-true x, y, sin(A/2). - DEFB $06 ;;forward to L23A3, DR-SIN-NZ - ;;if sin(r/2) is not zero. + DEFB $A2 ;;stk-half x, y, A, 1/2. + DEFB $04 ;;multiply x, y, A/2. + DEFB $1F ;;sin x, y, sin(A/2). + DEFB $31 ;;duplicate x, y, sin(A/2),sin(A/2) + DEFB $30 ;;not x, y, sin(A/2), (0/1). + DEFB $30 ;;not x, y, sin(A/2), (1/0). + DEFB $00 ;;jump-true x, y, sin(A/2). + DEFB $06 ;;forward to L23A3, DR-SIN-NZ + ;;if sin(r/2) is not zero. ; The third parameter is 2*PI (or a multiple of 2*PI) so a 360 degrees turn ; would just be a straight line. Eliminating this case here prevents ; division by zero at later stage. - DEFB $02 ;;delete x, y. - DEFB $38 ;;end-calc x, y. - JP L2477 + DEFB $02 ;;delete x, y. + DEFB $38 ;;end-calc x, y. + JP L2477 ; --- ; An arc can be drawn. ;; DR-SIN-NZ - DEFB $C0 ;;st-mem-0 x, y, sin(A/2). store mem-0 - DEFB $02 ;;delete x, y. + DEFB $C0 ;;st-mem-0 x, y, sin(A/2). store mem-0 + DEFB $02 ;;delete x, y. ; The next step calculates (roughly) the diameter of the circle of which the ; arc will form part. This value does not have to be too accurate as it is ; only used to evaluate the number of straight lines and then discarded. @@ -857,38 +884,38 @@ DRAW3: ; So that simple arithmetic can be used, the length of the chord can be ; calculated as X+Y rather than by Pythagoras Theorem and the sine of the ; nearest angle within reach is used. - DEFB $C1 ;;st-mem-1 x, y. store mem-1 - DEFB $02 ;;delete x. - DEFB $31 ;;duplicate x, x. - DEFB $2A ;;abs x, x (+ve). - DEFB $E1 ;;get-mem-1 x, X, y. - DEFB $01 ;;exchange x, y, X. - DEFB $E1 ;;get-mem-1 x, y, X, y. - DEFB $2A ;;abs x, y, X, Y (+ve). - DEFB $0F ;;addition x, y, X+Y. - DEFB $E0 ;;get-mem-0 x, y, X+Y, sin(A/2). - DEFB $05 ;;division x, y, X+Y/sin(A/2). - DEFB $2A ;;abs x, y, X+Y/sin(A/2) = D. + DEFB $C1 ;;st-mem-1 x, y. store mem-1 + DEFB $02 ;;delete x. + DEFB $31 ;;duplicate x, x. + DEFB $2A ;;abs x, x (+ve). + DEFB $E1 ;;get-mem-1 x, X, y. + DEFB $01 ;;exchange x, y, X. + DEFB $E1 ;;get-mem-1 x, y, X, y. + DEFB $2A ;;abs x, y, X, Y (+ve). + DEFB $0F ;;addition x, y, X+Y. + DEFB $E0 ;;get-mem-0 x, y, X+Y, sin(A/2). + DEFB $05 ;;division x, y, X+Y/sin(A/2). + DEFB $2A ;;abs x, y, X+Y/sin(A/2) = D. ; Bring back sin(A/2) from mem-0 which will shortly get trashed. ; Then bring D to the top of the stack again. - DEFB $E0 ;;get-mem-0 x, y, D, sin(A/2). - DEFB $01 ;;exchange x, y, sin(A/2), D. + DEFB $E0 ;;get-mem-0 x, y, D, sin(A/2). + DEFB $01 ;;exchange x, y, sin(A/2), D. ; Note. that since the value at the top of the stack has arisen as a result ; of division then it can no longer be in integer form and the next re-stack ; is unnecessary. Only the Sinclair ZX80 had integer division. - ;;DEFB $3D ;;re-stack (unnecessary) - DEFB $38 ;;end-calc x, y, sin(A/2), D. + ;;DEFB $3D ;;re-stack (unnecessary) + DEFB $38 ;;end-calc x, y, sin(A/2), D. ; The next test avoids drawing 4 straight lines when the start and end pixels ; are adjacent (or the same) but is probably best dispensed with. - LD A,(HL) ; fetch exponent byte of D. - CP $81 ; compare to 1 - JR NC,L23C1 ; forward, if > 1, to DR-PRMS + LD A,(HL) ; fetch exponent byte of D. + CP $81 ; compare to 1 + JR NC,L23C1 ; forward, if > 1, to DR-PRMS ; else delete the top two stack values and draw a simple straight line. - RST 28H ;; FP-CALC - DEFB $02 ;;delete - DEFB $02 ;;delete - DEFB $38 ;;end-calc x, y. - JP L2477 ; to LINE-DRAW + RST 28H ;; FP-CALC + DEFB $02 ;;delete + DEFB $02 ;;delete + DEFB $38 ;;end-calc x, y. + JP L2477 ; to LINE-DRAW ; --- ; The ARC will consist of multiple straight lines so call the CIRCLE-DRAW ; PARAMETERS ROUTINE to pre-calculate sine values from the angle (in mem-5) @@ -896,41 +923,41 @@ DRAW3: ; 'diameter' which is at the top of the calculator stack. ;; DR-PRMS L23C1: CALL 247Dh ; routine CD-PRMS1 - ; mem-0 ; (A)/No. of lines (=a) (step angle) - ; mem-1 ; sin(a/2) - ; mem-2 ; - - ; mem-3 ; cos(a) const - ; mem-4 ; sin(a) const - ; mem-5 ; Angle of rotation (A) in - ; B ; Count of straight lines - max 252. - PUSH BC ; Save the line count on the machine stack. + ; mem-0 ; (A)/No. of lines (=a) (step angle) + ; mem-1 ; sin(a/2) + ; mem-2 ; - + ; mem-3 ; cos(a) const + ; mem-4 ; sin(a) const + ; mem-5 ; Angle of rotation (A) in + ; B ; Count of straight lines - max 252. + PUSH BC ; Save the line count on the machine stack. ; Remove the now redundant diameter value D. - RST 28H ;; FP-CALC x, y, sin(A/2), D. - DEFB $02 ;;delete x, y, sin(A/2). + RST 28H ;; FP-CALC x, y, sin(A/2), D. + DEFB $02 ;;delete x, y, sin(A/2). ; Dividing the sine of the step angle by the sine of the total angle gives ; the length of the initial chord on a unary circle. This factor f is used ; to scale the coordinates of the first line which still points in the ; direction of the end point and may be larger. - DEFB $E1 ;;get-mem-1 x, y, sin(A/2), sin(a/2) - DEFB $01 ;;exchange x, y, sin(a/2), sin(A/2) - DEFB $05 ;;division x, y, sin(a/2)/sin(A/2) - DEFB $C1 ;;st-mem-1 x, y. f. - DEFB $02 ;;delete x, y. + DEFB $E1 ;;get-mem-1 x, y, sin(A/2), sin(a/2) + DEFB $01 ;;exchange x, y, sin(a/2), sin(A/2) + DEFB $05 ;;division x, y, sin(a/2)/sin(A/2) + DEFB $C1 ;;st-mem-1 x, y. f. + DEFB $02 ;;delete x, y. ; With the factor stored, scale the x coordinate first. - DEFB $01 ;;exchange y, x. - DEFB $31 ;;duplicate y, x, x. - DEFB $E1 ;;get-mem-1 y, x, x, f. - DEFB $04 ;;multiply y, x, x*f (=xx) - DEFB $C2 ;;st-mem-2 y, x, xx. - DEFB $02 ;;delete y. x. + DEFB $01 ;;exchange y, x. + DEFB $31 ;;duplicate y, x, x. + DEFB $E1 ;;get-mem-1 y, x, x, f. + DEFB $04 ;;multiply y, x, x*f (=xx) + DEFB $C2 ;;st-mem-2 y, x, xx. + DEFB $02 ;;delete y. x. ; Now scale the y coordinate. - DEFB $01 ;;exchange x, y. - DEFB $31 ;;duplicate x, y, y. - DEFB $E1 ;;get-mem-1 x, y, y, f - DEFB $04 ;;multiply x, y, y*f (=yy) + DEFB $01 ;;exchange x, y. + DEFB $31 ;;duplicate x, y, y. + DEFB $E1 ;;get-mem-1 x, y, y, f + DEFB $04 ;;multiply x, y, y*f (=yy) ; Note. 'sin' and 'cos' trash locations mem-0 to mem-2 so fetch mem-2 to the ; calculator stack for safe keeping. - DEFB $E2 ;;get-mem-2 x, y, yy, xx. + DEFB $E2 ;;get-mem-2 x, y, yy, xx. ; Once we get the coordinates of the first straight line then the 'ROTATION ; FORMULA' used in the arc loop will take care of all other points, but we ; now use a variation of that formula to rotate the first arc through (A-a)/2 @@ -939,84 +966,84 @@ L23C1: CALL 247Dh ; routine CD-PRMS1 ; xRotated = y * sin(angle) + x * cos(angle) ; yRotated = y * cos(angle) - x * sin(angle) ; - DEFB $E5 ;;get-mem-5 x, y, yy, xx, A. - DEFB $E0 ;;get-mem-0 x, y, yy, xx, A, a. - DEFB $03 ;;subtract x, y, yy, xx, A-a. - DEFB $A2 ;;stk-half x, y, yy, xx, A-a, 1/2. - DEFB $04 ;;multiply x, y, yy, xx, (A-a)/2. (=angle) - DEFB $31 ;;duplicate x, y, yy, xx, angle, angle. - DEFB $1F ;;sin x, y, yy, xx, angle, sin(angle) - DEFB $C5 ;;st-mem-5 x, y, yy, xx, angle, sin(angle) - DEFB $02 ;;delete x, y, yy, xx, angle - DEFB $20 ;;cos x, y, yy, xx, cos(angle). + DEFB $E5 ;;get-mem-5 x, y, yy, xx, A. + DEFB $E0 ;;get-mem-0 x, y, yy, xx, A, a. + DEFB $03 ;;subtract x, y, yy, xx, A-a. + DEFB $A2 ;;stk-half x, y, yy, xx, A-a, 1/2. + DEFB $04 ;;multiply x, y, yy, xx, (A-a)/2. (=angle) + DEFB $31 ;;duplicate x, y, yy, xx, angle, angle. + DEFB $1F ;;sin x, y, yy, xx, angle, sin(angle) + DEFB $C5 ;;st-mem-5 x, y, yy, xx, angle, sin(angle) + DEFB $02 ;;delete x, y, yy, xx, angle + DEFB $20 ;;cos x, y, yy, xx, cos(angle). ; Note. mem-0, mem-1 and mem-2 can be used again now... - DEFB $C0 ;;st-mem-0 x, y, yy, xx, cos(angle). - DEFB $02 ;;delete x, y, yy, xx. - DEFB $C2 ;;st-mem-2 x, y, yy, xx. - DEFB $02 ;;delete x, y, yy. - DEFB $C1 ;;st-mem-1 x, y, yy. - DEFB $E5 ;;get-mem-5 x, y, yy, sin(angle) - DEFB $04 ;;multiply x, y, yy*sin(angle). - DEFB $E0 ;;get-mem-0 x, y, yy*sin(angle), cos(angle) - DEFB $E2 ;;get-mem-2 x, y, yy*sin(angle), cos(angle), xx. - DEFB $04 ;;multiply x, y, yy*sin(angle), xx*cos(angle). - DEFB $0F ;;addition x, y, xRotated. - DEFB $E1 ;;get-mem-1 x, y, xRotated, yy. - DEFB $01 ;;exchange x, y, yy, xRotated. - DEFB $C1 ;;st-mem-1 x, y, yy, xRotated. - DEFB $02 ;;delete x, y, yy. - DEFB $E0 ;;get-mem-0 x, y, yy, cos(angle). - DEFB $04 ;;multiply x, y, yy*cos(angle). - DEFB $E2 ;;get-mem-2 x, y, yy*cos(angle), xx. - DEFB $E5 ;;get-mem-5 x, y, yy*cos(angle), xx, sin(angle). - DEFB $04 ;;multiply x, y, yy*cos(angle), xx*sin(angle). - DEFB $03 ;;subtract x, y, yRotated. - DEFB $C2 ;;st-mem-2 x, y, yRotated. + DEFB $C0 ;;st-mem-0 x, y, yy, xx, cos(angle). + DEFB $02 ;;delete x, y, yy, xx. + DEFB $C2 ;;st-mem-2 x, y, yy, xx. + DEFB $02 ;;delete x, y, yy. + DEFB $C1 ;;st-mem-1 x, y, yy. + DEFB $E5 ;;get-mem-5 x, y, yy, sin(angle) + DEFB $04 ;;multiply x, y, yy*sin(angle). + DEFB $E0 ;;get-mem-0 x, y, yy*sin(angle), cos(angle) + DEFB $E2 ;;get-mem-2 x, y, yy*sin(angle), cos(angle), xx. + DEFB $04 ;;multiply x, y, yy*sin(angle), xx*cos(angle). + DEFB $0F ;;addition x, y, xRotated. + DEFB $E1 ;;get-mem-1 x, y, xRotated, yy. + DEFB $01 ;;exchange x, y, yy, xRotated. + DEFB $C1 ;;st-mem-1 x, y, yy, xRotated. + DEFB $02 ;;delete x, y, yy. + DEFB $E0 ;;get-mem-0 x, y, yy, cos(angle). + DEFB $04 ;;multiply x, y, yy*cos(angle). + DEFB $E2 ;;get-mem-2 x, y, yy*cos(angle), xx. + DEFB $E5 ;;get-mem-5 x, y, yy*cos(angle), xx, sin(angle). + DEFB $04 ;;multiply x, y, yy*cos(angle), xx*sin(angle). + DEFB $03 ;;subtract x, y, yRotated. + DEFB $C2 ;;st-mem-2 x, y, yRotated. ; Now the initial x and y coordinates are made positive and summed to see ; if they measure up to anything significant. - DEFB $2A ;;abs x, y, yRotated'. - DEFB $E1 ;;get-mem-1 x, y, yRotated', xRotated. - DEFB $2A ;;abs x, y, yRotated', xRotated'. - DEFB $0F ;;addition x, y, yRotated+xRotated. - DEFB $02 ;;delete x, y. - DEFB $38 ;;end-calc x, y. + DEFB $2A ;;abs x, y, yRotated'. + DEFB $E1 ;;get-mem-1 x, y, yRotated', xRotated. + DEFB $2A ;;abs x, y, yRotated', xRotated'. + DEFB $0F ;;addition x, y, yRotated+xRotated. + DEFB $02 ;;delete x, y. + DEFB $38 ;;end-calc x, y. ; Although the test value has been deleted it is still above the calculator ; stack in memory and conveniently DE which points to the first free byte ; addresses the exponent of the test value. - LD A,(DE) ; Fetch exponent of the length indicator. - CP $81 ; Compare to that for 1 - POP BC ; Balance the machine stack - JP C,L2477 ; forward, if the coordinates of first line - ; don't add up to more than 1, to LINE-DRAW + LD A,(DE) ; Fetch exponent of the length indicator. + CP $81 ; Compare to that for 1 + POP BC ; Balance the machine stack + JP C,L2477 ; forward, if the coordinates of first line + ; don't add up to more than 1, to LINE-DRAW ; Continue when the arc will have a discernable shape. - PUSH BC ; Restore line counter to the machine stack. + PUSH BC ; Restore line counter to the machine stack. ; The parameters of the DRAW command were relative and they are now converted ; to absolute coordinates by adding to the coordinates of the last point ; plotted. The first two values on the stack are the terminal tx and ty ; coordinates. The x-coordinate is converted first but first the last point ; plotted is saved as it will initialize the moving ax, value. - RST 28H ;; FP-CALC x, y. - DEFB $01 ;;exchange y, x. - DEFB $38 ;;end-calc y, x. - LD A,(COORDS) ;; Fetch System Variable COORDS-x - CALL L2D28 ;; routine STACK-A - RST 28H ;; FP-CALC y, x, last-x. + RST 28H ;; FP-CALC x, y. + DEFB $01 ;;exchange y, x. + DEFB $38 ;;end-calc y, x. + LD A,(COORDS) ;; Fetch System Variable COORDS-x + CALL L2D28 ;; routine STACK-A + RST 28H ;; FP-CALC y, x, last-x. ; Store the last point plotted to initialize the moving ax value. - DEFB $C0 ;;st-mem-0 y, x, last-x. - DEFB $0F ;;addition y, absolute x. - DEFB $01 ;;exchange tx, y. - DEFB $38 ;;end-calc tx, y. - LD A,(COORDS + 1) ; Fetch System Variable COORDS-y - CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC tx, y, last-y. + DEFB $C0 ;;st-mem-0 y, x, last-x. + DEFB $0F ;;addition y, absolute x. + DEFB $01 ;;exchange tx, y. + DEFB $38 ;;end-calc tx, y. + LD A,(COORDS + 1) ; Fetch System Variable COORDS-y + CALL L2D28 ; routine STACK-A + RST 28H ;; FP-CALC tx, y, last-y. ; Store the last point plotted to initialize the moving ay value. - DEFB $C5 ;;st-mem-5 tx, y, last-y. - DEFB $0F ;;addition tx, ty. + DEFB $C5 ;;st-mem-5 tx, y, last-y. + DEFB $0F ;;addition tx, ty. ; Fetch the moving ax and ay to the calculator stack. - DEFB $E0 ;;get-mem-0 tx, ty, ax. - DEFB $E5 ;;get-mem-5 tx, ty, ax, ay. - DEFB $38 ;;end-calc tx, ty, ax, ay. - POP BC ; Restore the straight line count. + DEFB $E0 ;;get-mem-0 tx, ty, ax. + DEFB $E5 ;;get-mem-5 tx, ty, ax, ay. + DEFB $38 ;;end-calc tx, ty, ax, ay. + POP BC ; Restore the straight line count. ; ----------------------------------- ; THE 'CIRCLE/DRAW CONVERGENCE POINT' ; ----------------------------------- @@ -1028,8 +1055,8 @@ L23C1: CALL 247Dh ; routine CD-PRMS1 ; the jump will always be made to ARC-START. ;; DRW-STEPS L2420: DEC B ; decrement the arc count (4,8,12,16...). - ;JR Z,L245F ; forward, if zero (not possible), to ARC-END - JP L2439 ; forward to ARC-START + ;JR Z,L245F ; forward, if zero (not possible), to ARC-END + JP L2439 ; forward to ARC-START ; -------------- ; THE 'ARC LOOP' ; -------------- @@ -1058,25 +1085,25 @@ L2420: DEC B ; decrement the arc count (4,8,12,16...). ; the formula returns the next relative coordinates to use. ;; ARC-LOOP L2425: RST 28H ;; FP-CALC - DEFB $E1 ;;get-mem-1 rx. - DEFB $31 ;;duplicate rx, rx. - DEFB $E3 ;;get-mem-3 cos(a) - DEFB $04 ;;multiply rx, rx*cos(a). - DEFB $E2 ;;get-mem-2 rx, rx*cos(a), ry. - DEFB $E4 ;;get-mem-4 rx, rx*cos(a), ry, sin(a). - DEFB $04 ;;multiply rx, rx*cos(a), ry*sin(a). - DEFB $03 ;;subtract rx, rx*cos(a) - ry*sin(a) - DEFB $C1 ;;st-mem-1 rx, new relative x rotated. - DEFB $02 ;;delete rx. - DEFB $E4 ;;get-mem-4 rx, sin(a). - DEFB $04 ;;multiply rx*sin(a) - DEFB $E2 ;;get-mem-2 rx*sin(a), ry. - DEFB $E3 ;;get-mem-3 rx*sin(a), ry, cos(a). - DEFB $04 ;;multiply rx*sin(a), ry*cos(a). - DEFB $0F ;;addition rx*sin(a) + ry*cos(a). - DEFB $C2 ;;st-mem-2 new relative y rotated. - DEFB $02 ;;delete . - DEFB $38 ;;end-calc . + DEFB $E1 ;;get-mem-1 rx. + DEFB $31 ;;duplicate rx, rx. + DEFB $E3 ;;get-mem-3 cos(a) + DEFB $04 ;;multiply rx, rx*cos(a). + DEFB $E2 ;;get-mem-2 rx, rx*cos(a), ry. + DEFB $E4 ;;get-mem-4 rx, rx*cos(a), ry, sin(a). + DEFB $04 ;;multiply rx, rx*cos(a), ry*sin(a). + DEFB $03 ;;subtract rx, rx*cos(a) - ry*sin(a) + DEFB $C1 ;;st-mem-1 rx, new relative x rotated. + DEFB $02 ;;delete rx. + DEFB $E4 ;;get-mem-4 rx, sin(a). + DEFB $04 ;;multiply rx*sin(a) + DEFB $E2 ;;get-mem-2 rx*sin(a), ry. + DEFB $E3 ;;get-mem-3 rx*sin(a), ry, cos(a). + DEFB $04 ;;multiply rx*sin(a), ry*cos(a). + DEFB $0F ;;addition rx*sin(a) + ry*cos(a). + DEFB $C2 ;;st-mem-2 new relative y rotated. + DEFB $02 ;;delete . + DEFB $38 ;;end-calc . ; Note. the calculator stack actually holds tx, ty, ax, ay ; and the last absolute values of x and y ; are now brought into play. @@ -1096,38 +1123,38 @@ L2425: RST 28H ;; FP-CALC ;; ARC-START L2439: PUSH BC ; Preserve the arc counter on the machine stack. ; Store the absolute ay in temporary variable mem-0 for the moment. - RST 28H ;; FP-CALC ax, ay. - DEFB $C0 ;;st-mem-0 ax, ay. - DEFB $02 ;;delete ax. + RST 28H ;; FP-CALC ax, ay. + DEFB $C0 ;;st-mem-0 ax, ay. + DEFB $02 ;;delete ax. ; Now add the fractional relative x coordinate to the fractional absolute ; x coordinate to obtain a new fractional x-coordinate. - DEFB $E1 ;;get-mem-1 ax, xr. - DEFB $0F ;;addition ax+xr (= new ax). - DEFB $31 ;;duplicate ax, ax. - DEFB $38 ;;end-calc ax, ax. - LD A,(COORDS) ; COORDS-x last x (integer ix 0-255) - CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC ax, ax, ix. - DEFB $03 ;;subtract ax, ax-ix = relative DRAW Dx. + DEFB $E1 ;;get-mem-1 ax, xr. + DEFB $0F ;;addition ax+xr (= new ax). + DEFB $31 ;;duplicate ax, ax. + DEFB $38 ;;end-calc ax, ax. + LD A,(COORDS) ; COORDS-x last x (integer ix 0-255) + CALL L2D28 ; routine STACK-A + RST 28H ;; FP-CALC ax, ax, ix. + DEFB $03 ;;subtract ax, ax-ix = relative DRAW Dx. ; Having calculated the x value for DRAW do the same for the y value. - DEFB $E0 ;;get-mem-0 ax, Dx, ay. - DEFB $E2 ;;get-mem-2 ax, Dx, ay, ry. - DEFB $0F ;;addition ax, Dx, ay+ry (= new ay). - DEFB $C0 ;;st-mem-0 ax, Dx, ay. - DEFB $01 ;;exchange ax, ay, Dx, - DEFB $E0 ;;get-mem-0 ax, ay, Dx, ay. - DEFB $38 ;;end-calc ax, ay, Dx, ay. - LD A,(COORDS + 1) ; COORDS-y last y (integer iy 0-175) - CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC ax, ay, Dx, ay, iy. - DEFB $03 ;;subtract ax, ay, Dx, ay-iy ( = Dy). - DEFB $38 ;;end-calc ax, ay, Dx, Dy. - CALL L2477 ; Routine DRAW-LINE draws (Dx,Dy) relative to - ; the last pixel plotted leaving absolute x - ; and y on the calculator stack. - ; ax, ay. - POP BC ; Restore the arc counter from the machine stack. - DJNZ L2425 ; Decrement and loop while > 0 to ARC-LOOP + DEFB $E0 ;;get-mem-0 ax, Dx, ay. + DEFB $E2 ;;get-mem-2 ax, Dx, ay, ry. + DEFB $0F ;;addition ax, Dx, ay+ry (= new ay). + DEFB $C0 ;;st-mem-0 ax, Dx, ay. + DEFB $01 ;;exchange ax, ay, Dx, + DEFB $E0 ;;get-mem-0 ax, ay, Dx, ay. + DEFB $38 ;;end-calc ax, ay, Dx, ay. + LD A,(COORDS + 1) ; COORDS-y last y (integer iy 0-175) + CALL L2D28 ; routine STACK-A + RST 28H ;; FP-CALC ax, ay, Dx, ay, iy. + DEFB $03 ;;subtract ax, ay, Dx, ay-iy ( = Dy). + DEFB $38 ;;end-calc ax, ay, Dx, Dy. + CALL L2477 ; Routine DRAW-LINE draws (Dx,Dy) relative to + ; the last pixel plotted leaving absolute x + ; and y on the calculator stack. + ; ax, ay. + POP BC ; Restore the arc counter from the machine stack. + DJNZ L2425 ; Decrement and loop while > 0 to ARC-LOOP ; ------------- ; THE 'ARC END' ; ------------- @@ -1140,117 +1167,121 @@ L2439: PUSH BC ; Preserve the arc counter on the machine stack. ; can be deleted to expose the closing coordinates. ;; ARC-END L245F: RST 28H ;; FP-CALC tx, ty, ax, ay. - DEFB $02 ;;delete tx, ty, ax. - DEFB $02 ;;delete tx, ty. - DEFB $01 ;;exchange ty, tx. - DEFB $38 ;;end-calc ty, tx. + DEFB $02 ;;delete tx, ty, ax. + DEFB $02 ;;delete tx, ty. + DEFB $01 ;;exchange ty, tx. + DEFB $38 ;;end-calc ty, tx. ; First calculate the relative x coordinate to the end-point. - LD A,($5C7D) ; COORDS-x - CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC ty, tx, coords_x. - DEFB $03 ;;subtract ty, rx. + LD A,($5C7D) ; COORDS-x + CALL L2D28 ; routine STACK-A + RST 28H ;; FP-CALC ty, tx, coords_x. + DEFB $03 ;;subtract ty, rx. ; Next calculate the relative y coordinate to the end-point. - DEFB $01 ;;exchange rx, ty. - DEFB $38 ;;end-calc rx, ty. - LD A,($5C7E) ; COORDS-y - CALL L2D28 ; routine STACK-A - RST 28H ;; FP-CALC rx, ty, coords_y - DEFB $03 ;;subtract rx, ry. - DEFB $38 ;;end-calc rx, ry. + DEFB $01 ;;exchange rx, ty. + DEFB $38 ;;end-calc rx, ty. + LD A,($5C7E) ; COORDS-y + CALL L2D28 ; routine STACK-A + RST 28H ;; FP-CALC rx, ty, coords_y + DEFB $03 ;;subtract rx, ry. + DEFB $38 ;;end-calc rx, ry. ; Finally draw the last straight line. L2477: - call STACK_TO_BC ;;Pops x, and y, and stores it in B, C - ld hl, (COORDS) ;;Calculates x2 and y2 in L, H - rl e ;; Rotate left to carry - ld a, c - jr nc, SUM_C - neg + call STACK_TO_BC ;;Pops x, and y, and stores it in B, C + ld hl, (COORDS) ;;Calculates x2 and y2 in L, H + rl e ;; Rotate left to carry + ld a, c + jr nc, SUM_C + neg SUM_C: - add a, l - ld l, a ;; X2 - rl d ;; Low sign to carry - ld a, b - jr nc, SUM_B - neg + add a, l + ld l, a ;; X2 + rl d ;; Low sign to carry + ld a, b + jr nc, SUM_B + neg SUM_B: - add a, h - ld h, a - jp __DRAW ;;forward to LINE-DRAW (Fastcalled) - ENDP + add a, h + ld h, a + jp __DRAW ;;forward to LINE-DRAW (Fastcalled) + ENDP + pop namespace #line 75 "draw3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1267,10 +1298,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 76 "draw3.bas" END diff --git a/tests/functional/einar01.asm b/tests/functional/einar01.asm index 0827e4e30..34df26019 100644 --- a/tests/functional/einar01.asm +++ b/tests/functional/einar01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _score: DEFW __LABEL0 _score.__DATA__.__PTR__: @@ -28,16 +28,16 @@ _score.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_score.__DATA__ + 1) ld (_score.__DATA__ + 0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/einarattr.asm b/tests/functional/einarattr.asm index 404baf9a6..eb10c73a3 100644 --- a/tests/functional/einarattr.asm +++ b/tests/functional/einarattr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _printA ld hl, __LABEL0 xor a - call __PRINTSTR + call core.__PRINTSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,13 +49,13 @@ _printA: ld ix, 0 add ix, sp xor a - call PAPER_TMP + call core.PAPER_TMP ld a, 7 - call INK_TMP + call core.INK_TMP ld hl, __LABEL1 xor a - call __PRINTSTR - call COPY_ATTR + call core.__PRINTSTR + call core.COPY_ATTR _printA__leave: ld sp, ix pop ix @@ -75,70 +75,75 @@ __LABEL1: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -168,49 +173,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -218,267 +229,285 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -533,473 +562,478 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 43 "einarattr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1126,9 +1160,10 @@ __REFRESH_TMP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1136,37 +1171,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1176,134 +1212,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 46 "einarattr.bas" END diff --git a/tests/functional/einarshift.asm b/tests/functional/einarshift.asm index 6ba8502a7..ce220f742 100644 --- a/tests/functional/einarshift.asm +++ b/tests/functional/einarshift.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 03h _b: DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 3 ld hl, (_b - 1) sub h @@ -37,14 +37,14 @@ __LABEL0: add a, a djnz __LABEL0 __LABEL1: - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -61,70 +61,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -154,49 +159,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -204,319 +215,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -571,537 +602,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 31 "einarshift.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 32 "einarshift.bas" END diff --git a/tests/functional/elseif.asm b/tests/functional/elseif.asm index 849981235..2d680cd5c 100644 --- a/tests/functional/elseif.asm +++ b/tests/functional/elseif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _num: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_num) dec a jp nz, __LABEL0 @@ -43,9 +43,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/elseif1.asm b/tests/functional/elseif1.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/elseif1.asm +++ b/tests/functional/elseif1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/elseif2.asm b/tests/functional/elseif2.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/elseif2.asm +++ b/tests/functional/elseif2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/elseif3.asm b/tests/functional/elseif3.asm index 9a9fc2e96..e87ab4d46 100644 --- a/tests/functional/elseif3.asm +++ b/tests/functional/elseif3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL1 __LABEL0: xor a ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 ld hl, _a @@ -40,9 +40,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,8 +54,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -73,6 +74,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 32 "elseif3.bas" END diff --git a/tests/functional/elseif4.asm b/tests/functional/elseif4.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/elseif4.asm +++ b/tests/functional/elseif4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/elseif5.asm b/tests/functional/elseif5.asm index 8025487bc..3365c11da 100644 --- a/tests/functional/elseif5.asm +++ b/tests/functional/elseif5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL1 __LABEL0: xor a ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL3 __LABEL2: @@ -45,9 +45,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -78,6 +79,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 37 "elseif5.bas" END diff --git a/tests/functional/elseif6.asm b/tests/functional/elseif6.asm index 07dc3f36f..b43df4780 100644 --- a/tests/functional/elseif6.asm +++ b/tests/functional/elseif6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld hl, _a @@ -33,9 +33,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,8 +47,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -66,6 +67,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 25 "elseif6.bas" END diff --git a/tests/functional/emptystrparam.asm b/tests/functional/emptystrparam.asm index 8f9251cb2..68a5ffc94 100644 --- a/tests/functional/emptystrparam.asm +++ b/tests/functional/emptystrparam.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _stringtest ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _stringtest__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -189,9 +189,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -199,37 +200,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -239,94 +241,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 42 "emptystrparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -392,6 +396,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -421,6 +426,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -433,124 +439,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 43 "emptystrparam.bas" END diff --git a/tests/functional/end.asm b/tests/functional/end.asm index 737ca3980..e989eb2bb 100644 --- a/tests/functional/end.asm +++ b/tests/functional/end.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 35 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/endif.asm b/tests/functional/endif.asm index ad8336a02..fed7a8c5f 100644 --- a/tests/functional/endif.asm +++ b/tests/functional/endif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/eq0.asm b/tests/functional/eq0.asm index def995b1e..c87c29e9c 100644 --- a/tests/functional/eq0.asm +++ b/tests/functional/eq0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00, 00, 00, 00 _c: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_c) ld de, (_c + 1) ld bc, (_c + 3) ld hl, _b + 4 - call __FP_PUSH_REV - call __EQF + call core.__FP_PUSH_REV + call core.__EQF ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,146 +51,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -207,22 +212,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -237,19 +244,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -259,21 +267,24 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __EQF: ; A = B - call __FPSTACK_PUSH2 - ; ------------- ROM NOS-EQL - ld b, 0Eh ; For comparison operators, OP must be in B also - rst 28h - defb 0Eh - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 24 "eq0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -294,5 +305,6 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 25 "eq0.bas" END diff --git a/tests/functional/equ16.asm b/tests/functional/equ16.asm index 196cd34e0..e9c0af03b 100644 --- a/tests/functional/equ16.asm +++ b/tests/functional/equ16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, 5 ld hl, (_a) + call core.__EQ16 or a - sbc hl, de - jp nz, __LABEL1 + jp z, __LABEL1 ld hl, (_a) inc hl ld (_a), hl @@ -34,9 +34,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,12 +47,14 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/eq16.asm" + push namespace core __EQ16: ; Test if 16bit values HL == DE - ; Returns result in A: 0 = False, FF = True - xor a ; Reset carry flag - sbc hl, de - ret nz - inc a - ret + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace #line 26 "equ16.bas" END diff --git a/tests/functional/equ32.asm b/tests/functional/equ32.asm index 4aaa1daa5..ec5dbd542 100644 --- a/tests/functional/equ32.asm +++ b/tests/functional/equ32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 5 - call __EQ32 + call core.__EQ32 or a jp z, __LABEL1 ld de, 0 @@ -45,9 +45,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -58,27 +58,29 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/eq32.asm" + push namespace core __EQ32: ; Test if 32bit value HLDE equals top of the stack - ; Returns result in A: 0 = False, FF = True - exx - pop bc ; Return address - exx - xor a ; Reset carry flag - pop bc - sbc hl, bc ; Low part - ex de, hl - pop bc - sbc hl, bc ; High part - exx - push bc ; CALLEE - exx - ld a, h - or l - or d - or e ; a = 0 and Z flag set only if HLDE = 0 - ld a, 1 - ret z - xor a - ret + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace #line 37 "equ32.bas" END diff --git a/tests/functional/equ8.asm b/tests/functional/equ8.asm index 8b8766ec0..225313ff6 100644 --- a/tests/functional/equ8.asm +++ b/tests/functional/equ8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) sub 5 jp nz, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/explicit6.asm b/tests/functional/explicit6.asm index 87b52d297..1ccd0488b 100644 --- a/tests/functional/explicit6.asm +++ b/tests/functional/explicit6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (__LABEL__a), a __LABEL__a: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/extra_chars.asm b/tests/functional/extra_chars.asm index 6220b740a..80ee52e8b 100644 --- a/tests/functional/extra_chars.asm +++ b/tests/functional/extra_chars.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 3 "extra_chars.bas" `mylabel: ld a, #0 @@ -27,9 +27,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fact.asm b/tests/functional/fact.asm index dd21303db..2d5ddb311 100644 --- a/tests/functional/fact.asm +++ b/tests/functional/fact.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call CLS +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.CLS ld a, 1 ld (_x), a jp __LABEL0 __LABEL3: ld hl, __LABEL5 xor a - call __PRINTSTR + call core.__PRINTSTR ld a, (_x) - call __PRINTU8 + call core.__PRINTU8 ld hl, __LABEL6 xor a - call __PRINTSTR + call core.__PRINTSTR ld a, (_x) ld l, a ld h, 0 @@ -49,8 +49,8 @@ __LABEL3: push de push hl call _fact - call __PRINTU32 - call PRINT_EOL + call core.__PRINTU32 + call core.PRINT_EOL __LABEL4: ld hl, _x inc (hl) @@ -63,9 +63,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -86,7 +86,7 @@ _fact: push hl ld de, 0 ld hl, 2 - call __SUB32 + call core.__SUB32 jp nc, __LABEL8 ld de, 0 ld hl, 1 @@ -106,11 +106,11 @@ __LABEL8: push hl ld de, 0 ld hl, 1 - call __SUB32 + call core.__SUB32 push de push hl call _fact - call __MUL32 + call core.__MUL32 _fact__leave: ld sp, ix pop ix @@ -142,60 +142,64 @@ __LABEL6: ; Our faster implementation #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 109 "fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" @@ -203,75 +207,80 @@ __CLS_SCR: ; Used with permission. ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') ; 64bit result is returned in H'L'H L B'C'A C + push namespace core __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP - ret ; result in h'l'hlb'c'ac + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" -__MUL32: ; multiplies 32 bit un/signed integer. - ; First operand stored in DEHL, and 2nd onto stack - ; Lowest part of 2nd operand on top of the stack - ; returns the result in DE.HL - exx - pop hl ; Return ADDRESS - pop de ; Low part - ex (sp), hl ; CALLEE -> HL = High part - ex de, hl - call __MUL32_64START + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) - exx - push bc - exx - pop de - ld h, a - ld l, c - ret + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace #line 110 "fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -282,6 +291,7 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -311,49 +321,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -361,319 +377,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -728,422 +764,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 111 "fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1270,9 +1309,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1280,37 +1320,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1320,421 +1361,437 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 112 "fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 113 "fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 114 "fact.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sub32.asm" @@ -1742,24 +1799,26 @@ __PRINTU_LOOP: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 115 "fact.bas" END diff --git a/tests/functional/file_macro.asm b/tests/functional/file_macro.asm index 82ab559a5..9ee7fbb71 100644 --- a/tests/functional/file_macro.asm +++ b/tests/functional/file_macro.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -136,6 +136,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -165,7 +166,8 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret -#line 70 "/zxbasic/src/arch/zx48k/library-asm/error.asm" + pop namespace +#line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa @@ -290,9 +292,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -300,38 +303,39 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP -#line 70 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace +#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -343,91 +347,93 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP -#line 71 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace +#line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa @@ -496,95 +502,97 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP -#line 72 "/zxbasic/src/arch/zx48k/library-asm/free.asm" + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace +#line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC ; Reallocates a block of memory in the heap. @@ -605,132 +613,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP -#line 2 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace +#line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP -#line 14 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace +#line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -755,5 +768,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret -#line 36 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + pop namespace +#line 36 "file_macro.bas" END diff --git a/tests/functional/for0.asm b/tests/functional/for0.asm index a01c57453..2cfc6be0f 100644 --- a/tests/functional/for0.asm +++ b/tests/functional/for0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,52 +8,52 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call CLS +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.CLS ld a, 128 ld (_x), a jp __LABEL0 __LABEL3: ld a, (_x) - call __PRINTI8 + call core.__PRINTI8 ld hl, __LABEL5 xor a - call __PRINTSTR + call core.__PRINTSTR __LABEL4: ld hl, _x inc (hl) __LABEL0: ld a, 126 ld hl, (_x - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -73,65 +73,70 @@ __LABEL5: ; Our faster implementation #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 40 "for0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -149,6 +154,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 41 "for0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" @@ -162,6 +168,7 @@ checkParity: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -191,49 +198,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -241,319 +254,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -608,534 +641,543 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 42 "for0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1262,9 +1304,10 @@ __PRINTU_LOOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1272,37 +1315,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1312,134 +1356,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 43 "for0.bas" END diff --git a/tests/functional/for_const_crash.asm b/tests/functional/for_const_crash.asm index 9e660945b..326c197de 100644 --- a/tests/functional/for_const_crash.asm +++ b/tests/functional/for_const_crash.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _dw1: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 8192 ld (_dw1), hl jp __LABEL0 @@ -41,9 +41,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/forempty.asm b/tests/functional/forempty.asm index 2e94ddba6..cda85c28a 100644 --- a/tests/functional/forempty.asm +++ b/tests/functional/forempty.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_a), a jp __LABEL0 @@ -31,16 +31,16 @@ __LABEL4: __LABEL0: ld a, 1 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,8 +52,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -71,6 +72,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 30 "forempty.bas" END diff --git a/tests/functional/fornext.asm b/tests/functional/fornext.asm index 75f513e37..3d372847b 100644 --- a/tests/functional/fornext.asm +++ b/tests/functional/fornext.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: ld a, 1 ld (_i), a @@ -81,9 +81,9 @@ __LABEL17: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fornext2.asm b/tests/functional/fornext2.asm index a4bccfee0..517e0cad5 100644 --- a/tests/functional/fornext2.asm +++ b/tests/functional/fornext2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_x), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fornext3.asm b/tests/functional/fornext3.asm index 8c4366a2a..029e7ea69 100644 --- a/tests/functional/fornext3.asm +++ b/tests/functional/fornext3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld (_i), hl jp __LABEL0 @@ -40,9 +40,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fornextopt.asm b/tests/functional/fornextopt.asm index 4ce9fd780..c641f29cb 100644 --- a/tests/functional/fornextopt.asm +++ b/tests/functional/fornextopt.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a jp __LABEL0 diff --git a/tests/functional/fornextopt2.asm b/tests/functional/fornextopt2.asm index 0d71a93be..9245a62d2 100644 --- a/tests/functional/fornextopt2.asm +++ b/tests/functional/fornextopt2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 10 ld (_a), a jp __LABEL0 diff --git a/tests/functional/fornextopt3.asm b/tests/functional/fornextopt3.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/fornextopt3.asm +++ b/tests/functional/fornextopt3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fornextopt4.asm b/tests/functional/fornextopt4.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/fornextopt4.asm +++ b/tests/functional/fornextopt4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/forsplitted.asm b/tests/functional/forsplitted.asm index da5c72104..ab9ff4c06 100644 --- a/tests/functional/forsplitted.asm +++ b/tests/functional/forsplitted.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 _m: DEFB 00 _M: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__30: ld a, 1 ld (_i), a @@ -59,9 +59,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/forsplitted0.asm b/tests/functional/forsplitted0.asm index a9e5214d6..b671d6b00 100644 --- a/tests/functional/forsplitted0.asm +++ b/tests/functional/forsplitted0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL__20: ld a, 1 @@ -37,16 +37,16 @@ __LABEL4: __LABEL0: ld a, 10 ld hl, (_i - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -58,8 +58,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -77,6 +78,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 36 "forsplitted0.bas" END diff --git a/tests/functional/forsplitted1.asm b/tests/functional/forsplitted1.asm index 45daa5b47..9372a5b62 100644 --- a/tests/functional/forsplitted1.asm +++ b/tests/functional/forsplitted1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 _m: DEFB 00 _M: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_i), a jp __LABEL0 @@ -57,9 +57,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fporder.asm b/tests/functional/fporder.asm index 8b4aa7a1e..b5d81f2b7 100644 --- a/tests/functional/fporder.asm +++ b/tests/functional/fporder.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,46 +8,46 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _n: DEFB 81h DEFB 00h DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _n + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 082h ld de, 00F49h ld bc, 0A2DAh - call __MULF - call COS + call core.__MULF + call core.COS ld hl, 00000h push hl ld hl, 00020h push hl ld h, 084h push hl - call __SUBF + call core.__SUBF ld hl, _n - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -62,12 +62,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -82,26 +83,29 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/cos.asm" + push namespace core COS: ; Computes COS using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 20h ; COS - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 20h ; COS + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 33 "fporder.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- @@ -112,19 +116,22 @@ COS: ; Computes COS using ROM FP-CALC ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 34 "fporder.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -145,33 +152,36 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 35 "fporder.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 36 "fporder.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" ; ------------------------------------------------------------- @@ -182,13 +192,15 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __SUBF: ; Subtraction - call __FPSTACK_PUSH2 ; ENTERS B, A - ; ------------- ROM SUB - rst 28h - defb 01h ; EXCHANGE - defb 03h ; SUB - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; ENTERS B, A + ; ------------- ROM SUB + rst 28h + defb 01h ; EXCHANGE + defb 03h ; SUB + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 37 "fporder.bas" END diff --git a/tests/functional/func0.asm b/tests/functional/func0.asm index 84856f0ef..b32c5676c 100644 --- a/tests/functional/func0.asm +++ b/tests/functional/func0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/funccall0.asm b/tests/functional/funccall0.asm index 6f1843b51..c7fab4e84 100644 --- a/tests/functional/funccall0.asm +++ b/tests/functional/funccall0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/funccall1.asm b/tests/functional/funccall1.asm index d60957d26..79adf9b6c 100644 --- a/tests/functional/funccall1.asm +++ b/tests/functional/funccall1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test push af call _test2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/funccall2.asm b/tests/functional/funccall2.asm index 9e5be9460..be877d075 100644 --- a/tests/functional/funccall2.asm +++ b/tests/functional/funccall2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test __LABEL__anotherlabel: ld a, 5 @@ -32,9 +32,9 @@ __LABEL__anotherlabel: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/funcif.asm b/tests/functional/funcif.asm index b899d22c9..438b866a1 100644 --- a/tests/functional/funcif.asm +++ b/tests/functional/funcif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,41 +8,41 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00, 00, 00, 00 _y: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_y) ld de, (_y + 1) ld bc, (_y + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af call _ScanNear ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -85,77 +85,80 @@ _ScanNear__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -172,10 +175,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 61 "funcif.bas" END diff --git a/tests/functional/funcnoparm.asm b/tests/functional/funcnoparm.asm index e4e6066a7..fd4d240d3 100644 --- a/tests/functional/funcnoparm.asm +++ b/tests/functional/funcnoparm.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 push af call _xx @@ -32,9 +32,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/fwd_func_decl.asm b/tests/functional/fwd_func_decl.asm index 70e404936..691e10130 100644 --- a/tests/functional/fwd_func_decl.asm +++ b/tests/functional/fwd_func_decl.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/gef16.asm b/tests/functional/gef16.asm index 8c4a7288e..a417ac164 100644 --- a/tests/functional/gef16.asm +++ b/tests/functional/gef16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LTI32 + call core.__SWAP32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -69,7 +69,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -84,7 +84,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -96,9 +96,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -114,26 +114,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lti32.asm" + push namespace core __LTI32: ; Test 32 bit values in Top of the stack < HLDE PROC LOCAL checkParity @@ -153,12 +156,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 78 "gef16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -168,6 +173,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 79 "gef16.bas" END diff --git a/tests/functional/gei32.asm b/tests/functional/gei32.asm index 48827e1b4..2c1083145 100644 --- a/tests/functional/gei32.asm +++ b/tests/functional/gei32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LTI32 + call core.__SWAP32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -69,7 +69,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -84,7 +84,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -99,7 +99,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __LTI32 + call core.__LTI32 sub 1 sbc a, a ld l, a @@ -111,9 +111,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -129,26 +129,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lti32.asm" + push namespace core __LTI32: ; Test 32 bit values in Top of the stack < HLDE PROC LOCAL checkParity @@ -168,12 +171,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 93 "gei32.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -183,6 +188,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 94 "gei32.bas" END diff --git a/tests/functional/gei8.asm b/tests/functional/gei8.asm index 90d7e2241..763b2412a 100644 --- a/tests/functional/gei8.asm +++ b/tests/functional/gei8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld hl, (_a - 1) - call __LEI8 + call core.__LEI8 or a jp z, __LABEL1 ld a, 255 @@ -33,9 +33,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,8 +46,9 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -65,5 +66,6 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 25 "gei8.bas" END diff --git a/tests/functional/geu32.asm b/tests/functional/geu32.asm index 173fa3c9d..6990a57f6 100644 --- a/tests/functional/geu32.asm +++ b/tests/functional/geu32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __SUB32 + call core.__SWAP32 + call core.__SUB32 ccf sbc a, a ld l, a @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ccf sbc a, a ld l, a @@ -69,7 +69,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ccf sbc a, a ld l, a @@ -84,7 +84,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ccf sbc a, a ld l, a @@ -99,7 +99,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __SUB32 + call core.__SUB32 ccf sbc a, a ld l, a @@ -111,9 +111,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -128,31 +128,34 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 93 "geu32.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -162,6 +165,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 94 "geu32.bas" END diff --git a/tests/functional/gtf16.asm b/tests/functional/gtf16.asm index 7d132ed6f..4d36f5e3e 100644 --- a/tests/functional/gtf16.asm +++ b/tests/functional/gtf16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LEI32 + call core.__SWAP32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -69,7 +69,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -84,7 +84,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -96,9 +96,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -114,26 +114,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lei32.asm" + push namespace core __LEI32: ; Test 32 bit values Top of the stack <= HL,DE PROC LOCAL checkParity @@ -161,12 +164,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 78 "gtf16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -176,6 +181,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 79 "gtf16.bas" END diff --git a/tests/functional/gti32.asm b/tests/functional/gti32.asm index 35d69bfc7..cff09ecac 100644 --- a/tests/functional/gti32.asm +++ b/tests/functional/gti32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LEI32 + call core.__SWAP32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -69,7 +69,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -84,7 +84,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -99,7 +99,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __LEI32 + call core.__LEI32 sub 1 sbc a, a ld l, a @@ -111,9 +111,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -129,26 +129,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lei32.asm" + push namespace core __LEI32: ; Test 32 bit values Top of the stack <= HL,DE PROC LOCAL checkParity @@ -176,12 +179,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 93 "gti32.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -191,6 +196,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 94 "gti32.bas" END diff --git a/tests/functional/gti8.asm b/tests/functional/gti8.asm index 0e83ec6f0..417f5b89a 100644 --- a/tests/functional/gti8.asm +++ b/tests/functional/gti8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld hl, _a @@ -33,9 +33,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,8 +47,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -66,6 +67,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 25 "gti8.bas" END diff --git a/tests/functional/gtu32.asm b/tests/functional/gtu32.asm index 30c41a354..c761dabbb 100644 --- a/tests/functional/gtu32.asm +++ b/tests/functional/gtu32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,15 +30,15 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 + call core.__SWAP32 pop bc or a sbc hl, bc @@ -129,9 +129,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -144,8 +144,9 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -155,6 +156,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 111 "gtu32.bas" END diff --git a/tests/functional/gtu8.asm b/tests/functional/gtu8.asm index 544d000c1..d53515b1c 100644 --- a/tests/functional/gtu8.asm +++ b/tests/functional/gtu8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld hl, (_a - 1) cp h @@ -32,9 +32,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/haplo06.asm b/tests/functional/haplo06.asm index 47ac8de6b..f1f2e615a 100644 --- a/tests/functional/haplo06.asm +++ b/tests/functional/haplo06.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _y: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) ld a, (_a) or (hl) @@ -36,9 +36,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/haplo0asm.asm b/tests/functional/haplo0asm.asm index 9d34c8ca0..9c2785f30 100644 --- a/tests/functional/haplo0asm.asm +++ b/tests/functional/haplo0asm.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "haplo0asm.bas" tablaColor equ 2 tablaColorAlto equ tablaColor >> 8 @@ -35,9 +35,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/haplo_out.asm b/tests/functional/haplo_out.asm index 48d1c20c5..6050f00fc 100644 --- a/tests/functional/haplo_out.asm +++ b/tests/functional/haplo_out.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld bc, (_b) out (c), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/headerless.asm b/tests/functional/headerless.asm index 85eb10684..5120461d2 100644 --- a/tests/functional/headerless.asm +++ b/tests/functional/headerless.asm @@ -1,19 +1,20 @@ org 32768 -__START_PROGRAM: -ZXBASIC_USER_DATA: +core.__START_PROGRAM: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a inc (hl) ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: ret - END __START_PROGRAM + ;; --- end of user code --- + END core.__START_PROGRAM diff --git a/tests/functional/id_substr_eq_expr.asm b/tests/functional/id_substr_eq_expr.asm index 7f073034b..33debbc48 100644 --- a/tests/functional/id_substr_eq_expr.asm +++ b/tests/functional/id_substr_eq_expr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl xor a @@ -36,13 +36,13 @@ __MAIN_PROGRAM__: ld hl, 5 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -192,9 +192,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -202,37 +203,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -242,203 +244,207 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 34 "id_substr_eq_expr.bas" END diff --git a/tests/functional/idco.asm b/tests/functional/idco.asm index 74a97ed3b..fbcd0cb0f 100644 --- a/tests/functional/idco.asm +++ b/tests/functional/idco.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _p call _p call _p ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifcoendif.asm b/tests/functional/ifcoendif.asm index 42f2dda5f..4a1bf7b52 100644 --- a/tests/functional/ifcoendif.asm +++ b/tests/functional/ifcoendif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld hl, _a @@ -33,9 +33,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,8 +47,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -66,6 +67,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 25 "ifcoendif.bas" END diff --git a/tests/functional/ifcoendif1.asm b/tests/functional/ifcoendif1.asm index 1d80ef82f..6fd7fb702 100644 --- a/tests/functional/ifcoendif1.asm +++ b/tests/functional/ifcoendif1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld hl, _a @@ -33,9 +33,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,8 +47,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -66,6 +67,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 25 "ifcoendif1.bas" END diff --git a/tests/functional/ifcoendif2.asm b/tests/functional/ifcoendif2.asm index 68c3d3403..a916c3cf5 100644 --- a/tests/functional/ifcoendif2.asm +++ b/tests/functional/ifcoendif2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) cp 1 jp nc, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifcrash.asm b/tests/functional/ifcrash.asm index 5bf961a05..005d7c403 100644 --- a/tests/functional/ifcrash.asm +++ b/tests/functional/ifcrash.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _KEYSPACE: DEFB 00, 00, 00, 00, 00 _keyspacepressed: @@ -30,8 +30,8 @@ _nsfx: DEFB 00, 00, 00, 00, 00 _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_KEYSPACE) ld de, (_KEYSPACE + 1) ld bc, (_KEYSPACE + 3) @@ -42,26 +42,26 @@ __MAIN_PROGRAM__: or d jp z, __LABEL0 ld hl, _keyspacepressed + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 000h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp z, __LABEL3 ld hl, _nfires + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 000h ld de, 00000h ld bc, 00000h - call __GTF + call core.__GTF push af ld hl, _fire + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 000h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF ld h, a pop af or a @@ -73,26 +73,26 @@ __LABEL6: ld a, (_nsfx) ld de, (_nsfx + 1) ld bc, (_nsfx + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, 3 pop hl ld (hl), a ld hl, _nfires + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __SUBF + call core.__SUBF ld hl, _nfires - call __STOREF + call core.__STOREF ld a, 1 ld (_a), a ld a, 081h ld de, 00000h ld bc, 00000h ld hl, _keyspacepressed - call __STOREF + call core.__STOREF __LABEL5: __LABEL3: jp __LABEL1 @@ -101,14 +101,14 @@ __LABEL0: ld de, 00000h ld bc, 00000h ld hl, _keyspacepressed - call __STOREF + call core.__STOREF __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -121,146 +121,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -277,22 +282,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -307,19 +314,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -329,15 +337,17 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __EQF: ; A = B - call __FPSTACK_PUSH2 - ; ------------- ROM NOS-EQL - ld b, 0Eh ; For comparison operators, OP must be in B also - rst 28h - defb 0Eh - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 88 "ifcrash.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/gtf.asm" ; ------------------------------------------------------------- @@ -348,21 +358,24 @@ __EQF: ; A = B ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __GTF: ; A > B - call __FPSTACK_PUSH2 ; ENTERS B, A - ; ------------- ROM NOS-GRTR - ld b, 0Dh ; B < A - rst 28h - defb 0Dh ; B < A - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8; Convert to 8 bits + call __FPSTACK_PUSH2 ; ENTERS B, A + ; ------------- ROM NOS-GRTR + ld b, 0Dh ; B < A + rst 28h + defb 0Dh ; B < A + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8; Convert to 8 bits + pop namespace #line 90 "ifcrash.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -383,33 +396,36 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 91 "ifcrash.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 92 "ifcrash.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" ; ------------------------------------------------------------- @@ -420,13 +436,15 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __SUBF: ; Subtraction - call __FPSTACK_PUSH2 ; ENTERS B, A - ; ------------- ROM SUB - rst 28h - defb 01h ; EXCHANGE - defb 03h ; SUB - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; ENTERS B, A + ; ------------- ROM SUB + rst 28h + defb 01h ; EXCHANGE + defb 03h ; SUB + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 93 "ifcrash.bas" END diff --git a/tests/functional/ifelse0.asm b/tests/functional/ifelse0.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/ifelse0.asm +++ b/tests/functional/ifelse0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifelse1.asm b/tests/functional/ifelse1.asm index 8bfcec8f5..b359a39d2 100644 --- a/tests/functional/ifelse1.asm +++ b/tests/functional/ifelse1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,41 +8,41 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) sub 2 jp z, __LABEL1 __LABEL0: ld hl, __LABEL2 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -74,70 +74,75 @@ __LABEL2: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -167,49 +172,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -217,319 +228,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -584,422 +615,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 41 "ifelse1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1126,9 +1160,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1136,37 +1171,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1176,134 +1212,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 42 "ifelse1.bas" END diff --git a/tests/functional/ifelse2.asm b/tests/functional/ifelse2.asm index ec91cb544..27b6da3b5 100644 --- a/tests/functional/ifelse2.asm +++ b/tests/functional/ifelse2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _i @@ -36,7 +36,7 @@ __LABEL0: __LABEL1: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL2 ld hl, _i @@ -49,9 +49,9 @@ __LABEL3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -63,8 +63,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -82,6 +83,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 41 "ifelse2.bas" END diff --git a/tests/functional/ifelse3.asm b/tests/functional/ifelse3.asm index f61b1c108..b056b7bdf 100644 --- a/tests/functional/ifelse3.asm +++ b/tests/functional/ifelse3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _i @@ -37,9 +37,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,8 +51,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -70,6 +71,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 29 "ifelse3.bas" END diff --git a/tests/functional/ifelse4.asm b/tests/functional/ifelse4.asm index a44f83c72..bf9c95a9f 100644 --- a/tests/functional/ifelse4.asm +++ b/tests/functional/ifelse4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _i @@ -37,9 +37,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,8 +51,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -70,6 +71,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 29 "ifelse4.bas" END diff --git a/tests/functional/ifelse5.asm b/tests/functional/ifelse5.asm index 6fed227fb..2e289fc03 100644 --- a/tests/functional/ifelse5.asm +++ b/tests/functional/ifelse5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _i @@ -35,7 +35,7 @@ __LABEL0: dec (hl) ld h, 2 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 ld hl, _i @@ -45,9 +45,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -78,6 +79,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 37 "ifelse5.bas" END diff --git a/tests/functional/ifempty.asm b/tests/functional/ifempty.asm index 3df11dcf4..8a370d5d4 100644 --- a/tests/functional/ifempty.asm +++ b/tests/functional/ifempty.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifempty0.asm b/tests/functional/ifempty0.asm index 3df11dcf4..8a370d5d4 100644 --- a/tests/functional/ifempty0.asm +++ b/tests/functional/ifempty0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifempty1.asm b/tests/functional/ifempty1.asm index 3df11dcf4..8a370d5d4 100644 --- a/tests/functional/ifempty1.asm +++ b/tests/functional/ifempty1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifempty2.asm b/tests/functional/ifempty2.asm index a9f3f8310..acd86c4ff 100644 --- a/tests/functional/ifempty2.asm +++ b/tests/functional/ifempty2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL1 __LABEL0: @@ -34,9 +34,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,8 +48,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -67,6 +68,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 26 "ifempty2.bas" END diff --git a/tests/functional/ifempty3.asm b/tests/functional/ifempty3.asm index a1ae922bf..ea954cf57 100644 --- a/tests/functional/ifempty3.asm +++ b/tests/functional/ifempty3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _i @@ -37,9 +37,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,8 +51,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -70,6 +71,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 29 "ifempty3.bas" END diff --git a/tests/functional/ifempty4.asm b/tests/functional/ifempty4.asm index 3df11dcf4..8a370d5d4 100644 --- a/tests/functional/ifempty4.asm +++ b/tests/functional/ifempty4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifempty5.asm b/tests/functional/ifempty5.asm index 50c83faf4..0f807f29e 100644 --- a/tests/functional/ifempty5.asm +++ b/tests/functional/ifempty5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _i inc (hl) ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifempty6.asm b/tests/functional/ifempty6.asm index 9da99780d..f48584cab 100644 --- a/tests/functional/ifempty6.asm +++ b/tests/functional/ifempty6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _i dec (hl) ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifemptyelse.asm b/tests/functional/ifemptyelse.asm index 98b04bd50..0ab3bfca5 100644 --- a/tests/functional/ifemptyelse.asm +++ b/tests/functional/ifemptyelse.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a dec (hl) ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifemptylabel1.asm b/tests/functional/ifemptylabel1.asm index 081fcb4a6..cfc137eb4 100644 --- a/tests/functional/ifemptylabel1.asm +++ b/tests/functional/ifemptylabel1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: jp __LABEL1 __LABEL__Here: ld hl, _a diff --git a/tests/functional/ifemptylabel2.asm b/tests/functional/ifemptylabel2.asm index 3952ad5c2..6fe81c684 100644 --- a/tests/functional/ifemptylabel2.asm +++ b/tests/functional/ifemptylabel2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a inc (hl) jp __LABEL1 diff --git a/tests/functional/ifemptyprogelse.asm b/tests/functional/ifemptyprogelse.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/ifemptyprogelse.asm +++ b/tests/functional/ifemptyprogelse.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/iffor.asm b/tests/functional/iffor.asm index c8066e242..698eb4cfc 100644 --- a/tests/functional/iffor.asm +++ b/tests/functional/iffor.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld a, 1 @@ -37,7 +37,7 @@ __LABEL6: __LABEL2: ld a, 10 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL5 __LABEL4: @@ -45,9 +45,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -78,6 +79,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 37 "iffor.bas" END diff --git a/tests/functional/iffor1.asm b/tests/functional/iffor1.asm index 89ffa480e..93da029d2 100644 --- a/tests/functional/iffor1.asm +++ b/tests/functional/iffor1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld a, 1 @@ -37,7 +37,7 @@ __LABEL6: __LABEL2: ld a, 10 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL5 __LABEL4: @@ -45,9 +45,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -78,6 +79,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 37 "iffor1.bas" END diff --git a/tests/functional/iffor2.asm b/tests/functional/iffor2.asm index f54be6caa..14f47702a 100644 --- a/tests/functional/iffor2.asm +++ b/tests/functional/iffor2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 ld a, 1 @@ -33,7 +33,7 @@ __MAIN_PROGRAM__: __LABEL5: ld a, 1 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL8 ld hl, _a @@ -46,7 +46,7 @@ __LABEL13: __LABEL9: ld a, 10 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL12 __LABEL11: @@ -57,7 +57,7 @@ __LABEL6: __LABEL2: ld a, 10 ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL5 __LABEL4: @@ -65,9 +65,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -79,8 +79,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -98,6 +99,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 57 "iffor2.bas" END diff --git a/tests/functional/ififelseelse1.asm b/tests/functional/ififelseelse1.asm index 3c337649b..0fd6a4e5d 100644 --- a/tests/functional/ififelseelse1.asm +++ b/tests/functional/ififelseelse1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL__20: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _a inc (hl) ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL2 ld hl, _a @@ -54,9 +54,9 @@ __LABEL__30: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -68,8 +68,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -87,6 +88,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 46 "ififelseelse1.bas" END diff --git a/tests/functional/ififelseelse2.asm b/tests/functional/ififelseelse2.asm index 1ebc22c9b..5bdd09d2f 100644 --- a/tests/functional/ififelseelse2.asm +++ b/tests/functional/ififelseelse2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL__20: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _a inc (hl) ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL2 ld hl, _a @@ -54,9 +54,9 @@ __LABEL__30: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -68,8 +68,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -87,6 +88,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 46 "ififelseelse2.bas" END diff --git a/tests/functional/ifline.asm b/tests/functional/ifline.asm index 6b485e81c..500d5c916 100644 --- a/tests/functional/ifline.asm +++ b/tests/functional/ifline.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) dec a jp nz, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifthen.asm b/tests/functional/ifthen.asm index f920c5f6a..499f69cf7 100644 --- a/tests/functional/ifthen.asm +++ b/tests/functional/ifthen.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__5: __LABEL__10: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 __LABEL__20: @@ -36,7 +36,7 @@ __LABEL__30: __LABEL1: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 ld hl, _a @@ -45,9 +45,9 @@ __LABEL3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -78,6 +79,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 37 "ifthen.bas" END diff --git a/tests/functional/ifthencosntcoendif.asm b/tests/functional/ifthencosntcoendif.asm index ad8336a02..fed7a8c5f 100644 --- a/tests/functional/ifthencosntcoendif.asm +++ b/tests/functional/ifthencosntcoendif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifthenelse.asm b/tests/functional/ifthenelse.asm index 73e465646..ff5ce626a 100644 --- a/tests/functional/ifthenelse.asm +++ b/tests/functional/ifthenelse.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__5: __LABEL__10: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _a @@ -40,7 +40,7 @@ __LABEL__30: __LABEL1: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL2 ld hl, _a @@ -53,9 +53,9 @@ __LABEL3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -67,8 +67,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -86,6 +87,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 45 "ifthenelse.bas" END diff --git a/tests/functional/ifthenelseif.asm b/tests/functional/ifthenelseif.asm index b81046e2b..cf0a36699 100644 --- a/tests/functional/ifthenelseif.asm +++ b/tests/functional/ifthenelseif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__5: __LABEL__10: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _a @@ -36,7 +36,7 @@ __LABEL__20: __LABEL0: xor a ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 xor a @@ -47,7 +47,7 @@ __LABEL1: __LABEL__40: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL4 ld hl, _a @@ -57,7 +57,7 @@ __LABEL__50: __LABEL4: xor a ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL6 xor a @@ -75,7 +75,7 @@ __LABEL7: __LABEL5: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL10 ld hl, _a @@ -84,7 +84,7 @@ __LABEL5: __LABEL10: xor a ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL13 xor a @@ -93,7 +93,7 @@ __LABEL13: __LABEL11: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL14 ld hl, _a @@ -102,7 +102,7 @@ __LABEL11: __LABEL14: xor a ld hl, (_a - 1) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL16 xor a @@ -120,9 +120,9 @@ __LABEL15: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -134,8 +134,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -153,6 +154,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 112 "ifthenelseif.bas" END diff --git a/tests/functional/ifthenlblsntcoendif.asm b/tests/functional/ifthenlblsntcoendif.asm index 55ba8eb45..54afd5cc8 100644 --- a/tests/functional/ifthenlblsntcoendif.asm +++ b/tests/functional/ifthenlblsntcoendif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) jp __LABEL1 __LABEL__10: @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifthensntcoelsecocoendif.asm b/tests/functional/ifthensntcoelsecocoendif.asm index eb34fb2d3..1ec3c15e8 100644 --- a/tests/functional/ifthensntcoelsecocoendif.asm +++ b/tests/functional/ifthensntcoelsecocoendif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _a @@ -37,9 +37,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,8 +51,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -70,6 +71,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 29 "ifthensntcoelsecocoendif.bas" END diff --git a/tests/functional/ifthensntcoelsecoendif.asm b/tests/functional/ifthensntcoelsecoendif.asm index b1074178f..70d5cd9c2 100644 --- a/tests/functional/ifthensntcoelsecoendif.asm +++ b/tests/functional/ifthensntcoelsecoendif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 1 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL0 ld hl, _a @@ -37,9 +37,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,8 +51,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -70,6 +71,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 29 "ifthensntcoelsecoendif.bas" END diff --git a/tests/functional/ifthensntcoelselblco.asm b/tests/functional/ifthensntcoelselblco.asm index 12acbd745..4e4a26ed6 100644 --- a/tests/functional/ifthensntcoelselblco.asm +++ b/tests/functional/ifthensntcoelselblco.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) jp __LABEL0 __LABEL__10: @@ -36,9 +36,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifthensntcoelselblcoco.asm b/tests/functional/ifthensntcoelselblcoco.asm index 12acbd745..4e4a26ed6 100644 --- a/tests/functional/ifthensntcoelselblcoco.asm +++ b/tests/functional/ifthensntcoelselblcoco.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) jp __LABEL0 __LABEL__10: @@ -36,9 +36,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifthensntcoendif.asm b/tests/functional/ifthensntcoendif.asm index ad8336a02..fed7a8c5f 100644 --- a/tests/functional/ifthensntcoendif.asm +++ b/tests/functional/ifthensntcoendif.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ifwhile.asm b/tests/functional/ifwhile.asm index 5c75ae175..af0a2e474 100644 --- a/tests/functional/ifwhile.asm +++ b/tests/functional/ifwhile.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 __LABEL2: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 ld hl, _a @@ -41,9 +41,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,8 +55,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -74,6 +75,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 33 "ifwhile.bas" END diff --git a/tests/functional/ifwhile1.asm b/tests/functional/ifwhile1.asm index c90c0f724..e919ee698 100644 --- a/tests/functional/ifwhile1.asm +++ b/tests/functional/ifwhile1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 __LABEL2: ld h, 10 ld a, (_a) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 ld hl, _a @@ -41,9 +41,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,8 +55,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -74,6 +75,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 33 "ifwhile1.bas" END diff --git a/tests/functional/ifwhilex.asm b/tests/functional/ifwhilex.asm index 3d6016e89..46bb7a378 100644 --- a/tests/functional/ifwhilex.asm +++ b/tests/functional/ifwhilex.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld h, 0 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL1 __LABEL2: ld h, 10 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp z, __LABEL3 ld hl, _i @@ -39,15 +39,15 @@ __LABEL2: jp __LABEL2 __LABEL3: ld a, (_i) - call __PRINTI8 - call PRINT_EOL + call core.__PRINTI8 + call core.PRINT_EOL __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -78,6 +79,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 36 "ifwhilex.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" @@ -87,70 +89,75 @@ checkParity: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -180,49 +187,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -230,319 +243,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -597,535 +630,544 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 37 "ifwhilex.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 38 "ifwhilex.bas" END diff --git a/tests/functional/in0.asm b/tests/functional/in0.asm index 4e99a9360..2a95e4d52 100644 --- a/tests/functional/in0.asm +++ b/tests/functional/in0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld bc, 254 in a, (c) ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/init_with_dot.asm b/tests/functional/init_with_dot.asm index dbea11436..01713ad56 100644 --- a/tests/functional/init_with_dot.asm +++ b/tests/functional/init_with_dot.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei call A_LABEL.DOT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 3 "init_with_dot.bas" A_LABEL.DOT: #line 9 "init_with_dot.bas" ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/inkey.asm b/tests/functional/inkey.asm index ab932b7e3..0a23b45c3 100644 --- a/tests/functional/inkey.asm +++ b/tests/functional/inkey.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,44 +8,44 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call INKEY +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.INKEY ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, (_a) xor a - call __PRINTSTR - call PRINT_EOL_ATTR - call INKEY + call core.__PRINTSTR + call core.PRINT_EOL_ATTR + call core.INKEY ld a, 1 - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -123,6 +123,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -152,6 +153,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -217,9 +219,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -227,37 +230,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -270,133 +274,137 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" + push namespace core INKEY: - PROC - LOCAL __EMPTY_INKEY - LOCAL KEY_SCAN - LOCAL KEY_TEST - LOCAL KEY_CODE - ld bc, 3 ; 1 char length string - call __MEM_ALLOC - ld a, h - or l - ret z ; Return if NULL (No memory) - push hl ; Saves memory pointer - call KEY_SCAN - jp nz, __EMPTY_INKEY - call KEY_TEST - jp nc, __EMPTY_INKEY - dec d ; D is expected to be FLAGS so set bit 3 $FF - ; 'L' Mode so no keywords. - ld e, a ; main key to A - ; C is MODE 0 'KLC' from above still. - call KEY_CODE ; routine K-DECODE - pop hl - ld (hl), 1 - inc hl - ld (hl), 0 - inc hl - ld (hl), a - dec hl - dec hl ; HL Points to string result - ret + PROC + LOCAL __EMPTY_INKEY + LOCAL KEY_SCAN + LOCAL KEY_TEST + LOCAL KEY_CODE + ld bc, 3 ; 1 char length string + call __MEM_ALLOC + ld a, h + or l + ret z ; Return if NULL (No memory) + push hl ; Saves memory pointer + call KEY_SCAN + jp nz, __EMPTY_INKEY + call KEY_TEST + jp nc, __EMPTY_INKEY + dec d ; D is expected to be FLAGS so set bit 3 $FF + ; 'L' Mode so no keywords. + ld e, a ; main key to A + ; C is MODE 0 'KLC' from above still. + call KEY_CODE ; routine K-DECODE + pop hl + ld (hl), 1 + inc hl + ld (hl), 0 + inc hl + ld (hl), a + dec hl + dec hl ; HL Points to string result + ret __EMPTY_INKEY: - pop hl - xor a - ld (hl), a - inc hl - ld (hl), a - dec hl - ret + pop hl + xor a + ld (hl), a + inc hl + ld (hl), a + dec hl + ret KEY_SCAN EQU 028Eh KEY_TEST EQU 031Eh KEY_CODE EQU 0333h - ENDP + ENDP + pop namespace #line 29 "inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -405,109 +413,118 @@ __EMPTY_INKEY: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -515,319 +532,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -882,429 +919,434 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 30 "inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 31 "inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1375,135 +1417,139 @@ PRINT_EOL_ATTR: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 32 "inkey.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -1512,29 +1558,31 @@ __PRINT_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 33 "inkey.bas" END diff --git a/tests/functional/inktemp.asm b/tests/functional/inktemp.asm index cb72da5f5..1203c5be1 100644 --- a/tests/functional/inktemp.asm +++ b/tests/functional/inktemp.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,49 +8,49 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 2 - call INK_TMP + call core.INK_TMP ld hl, 255 push hl ld hl, 175 - call DRAW - call COPY_ATTR + call core.DRAW + call core.COPY_ATTR ld a, 7 - call PAPER_TMP + call core.PAPER_TMP ld a, 127 push af ld a, 128 - call PLOT - call COPY_ATTR + call core.PLOT + call core.COPY_ATTR ld a, 1 - call FLASH_TMP + call core.FLASH_TMP ld a, 1 - call OVER_TMP + call core.OVER_TMP ld a, 127 push af ld a, 87 push af ld a, 60 - call CIRCLE - call COPY_ATTR + call core.CIRCLE + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -66,6 +66,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -95,6 +96,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" ; MIXED __FASTCAL__ / __CALLE__ PLOT Function @@ -104,93 +106,100 @@ __STOP: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -198,7 +207,9 @@ __CLS_SCR: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -253,29 +264,31 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + push namespace core PLOT: - PROC - LOCAL PLOT_SUB - LOCAL PIXEL_ADDR - LOCAL COORDS - LOCAL __PLOT_ERR + PROC + LOCAL PLOT_SUB + LOCAL PIXEL_ADDR + LOCAL COORDS + LOCAL __PLOT_ERR LOCAL P_FLAG LOCAL __PLOT_OVER1 P_FLAG EQU 23697 - pop hl - ex (sp), hl ; Callee - ld b, a - ld c, h -#line 35 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 41 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" - ld a, 191 - cp b - jr c, __PLOT_ERR ; jr is faster here (#1) + pop hl + ex (sp), hl ; Callee + ld b, a + ld c, h +#line 37 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 43 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + ld a, 191 + cp b + jr c, __PLOT_ERR ; jr is faster here (#1) __PLOT: ; __FASTCALL__ entry (b, c) = pixel coords (y, x) - ld (COORDS), bc ; Saves current point - ld a, 191 ; Max y coord - call PIXEL_ADDR + ld (COORDS), bc ; Saves current point + ld a, 191 ; Max y coord + call PIXEL_ADDR res 6, h ; Starts from 0 ld bc, (SCREEN_ADDR) add hl, bc ; Now current offset @@ -307,202 +320,207 @@ __PLOT_ERR: PLOT_SUB EQU 22ECh PIXEL_ADDR EQU 22ACh COORDS EQU 5C7Dh - ENDP + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" ; Draws a circle at X, Y of radius R ; X, Y on the Stack, R in accumulator (Byte) - PROC - LOCAL __CIRCLE_ERROR - LOCAL __CIRCLE_LOOP - LOCAL __CIRCLE_NEXT + push namespace core + PROC + LOCAL __CIRCLE_ERROR + LOCAL __CIRCLE_LOOP + LOCAL __CIRCLE_NEXT __CIRCLE_ERROR: - jp __OUT_OF_SCREEN_ERR + jp __OUT_OF_SCREEN_ERR CIRCLE: - ;; Entry point - pop hl ; Return Address - pop de ; D = Y - ex (sp), hl ; __CALLEE__ convention - ld e, h ; E = X - ld h, a ; H = R -#line 31 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" - ld a, h - add a, d - sub 192 - jr nc, __CIRCLE_ERROR - ld a, d - sub h - jr c, __CIRCLE_ERROR - ld a, e - sub h - jr c, __CIRCLE_ERROR - ld a, h - add a, e - jr c, __CIRCLE_ERROR + ;; Entry point + pop hl ; Return Address + pop de ; D = Y + ex (sp), hl ; __CALLEE__ convention + ld e, h ; E = X + ld h, a ; H = R +#line 33 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" +#line 39 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" + ld a, h + add a, d + sub 192 + jr nc, __CIRCLE_ERROR + ld a, d + sub h + jr c, __CIRCLE_ERROR + ld a, e + sub h + jr c, __CIRCLE_ERROR + ld a, h + add a, e + jr c, __CIRCLE_ERROR ; __FASTCALL__ Entry: D, E = Y, X point of the center ; A = Radious __CIRCLE: - push de - ld a, h - exx - pop de ; D'E' = x0, y0 - ld h, a ; H' = r - ld c, e - ld a, h - add a, d - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 + r) - ld b, d - ld a, h - add a, e - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 + r, y0) - ld c, e - ld a, d - sub h - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 - r) - ld b, d - ld a, e - sub h - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 - r, y0) - exx - ld b, 0 ; B = x = 0 - ld c, h ; C = y = Radius - ld hl, 1 - or a - sbc hl, bc ; HL = f = 1 - radius - ex de, hl - ld hl, 0 - or a - sbc hl, bc ; HL = -radius - add hl, hl ; HL = -2 * radius - ex de, hl ; DE = -2 * radius = ddF_y, HL = f - xor a ; A = ddF_x = 0 - ex af, af' ; Saves it + push de + ld a, h + exx + pop de ; D'E' = x0, y0 + ld h, a ; H' = r + ld c, e + ld a, h + add a, d + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 + r) + ld b, d + ld a, h + add a, e + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 + r, y0) + ld c, e + ld a, d + sub h + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 - r) + ld b, d + ld a, e + sub h + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 - r, y0) + exx + ld b, 0 ; B = x = 0 + ld c, h ; C = y = Radius + ld hl, 1 + or a + sbc hl, bc ; HL = f = 1 - radius + ex de, hl + ld hl, 0 + or a + sbc hl, bc ; HL = -radius + add hl, hl ; HL = -2 * radius + ex de, hl ; DE = -2 * radius = ddF_y, HL = f + xor a ; A = ddF_x = 0 + ex af, af' ; Saves it __CIRCLE_LOOP: - ld a, b - cp c - ret nc ; Returns when x >= y - bit 7, h ; HL >= 0? : if (f >= 0)... - jp nz, __CIRCLE_NEXT - dec c ; y-- - inc de - inc de ; ddF_y += 2 - add hl, de ; f += ddF_y + ld a, b + cp c + ret nc ; Returns when x >= y + bit 7, h ; HL >= 0? : if (f >= 0)... + jp nz, __CIRCLE_NEXT + dec c ; y-- + inc de + inc de ; ddF_y += 2 + add hl, de ; f += ddF_y __CIRCLE_NEXT: - inc b ; x++ - ex af, af' - add a, 2 ; 1 Cycle faster than inc a, inc a - inc hl ; f++ - push af - add a, l - ld l, a - ld a, h - adc a, 0 ; f = f + ddF_x - ld h, a - pop af - ex af, af' - push bc - exx - pop hl ; H'L' = Y, X - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - sub h - ld c, a ; C = x0 - y - call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - sub h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) - exx - jp __CIRCLE_LOOP + inc b ; x++ + ex af, af' + add a, 2 ; 1 Cycle faster than inc a, inc a + inc hl ; f++ + push af + add a, l + ld l, a + ld a, h + adc a, 0 ; f = f + ddF_x + ld h, a + pop af + ex af, af' + push bc + exx + pop hl ; H'L' = Y, X + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + sub h + ld c, a ; C = x0 - y + call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + sub h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) + exx + jp __CIRCLE_LOOP __CIRCLE_PLOT: - ; Plots a point of the circle, preserving HL and DE - push hl - push de - call __PLOT - pop de - pop hl - ret - ENDP + ; Plots a point of the circle, preserving HL and DE + push hl + push de + call __PLOT + pop de + pop hl + ret + ENDP + pop namespace #line 42 "inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 43 "inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" ; DRAW using bresenhams algorithm and screen positioning @@ -525,32 +543,34 @@ __REFRESH_TMP: ; Carry'= moved off current cell (needs ATTR update) ; HL = moves one pixel down ; used : AF, HL + push namespace core SP.PixelDown: - inc h - ld a,h - and $07 - ret nz - ex af, af' ; Sets carry on F' - scf ; which flags ATTR must be updated - ex af, af' - ld a,h - sub $08 - ld h,a - ld a,l - add a,$20 - ld l,a - ret nc - ld a,h - add a,$08 - ld h,a + inc h + ld a,h + and $07 + ret nz + ex af, af' ; Sets carry on F' + scf ; which flags ATTR must be updated + ex af, af' + ld a,h + sub $08 + ld h,a + ld a,l + add a,$20 + ld l,a + ret nc + ld a,h + add a,$08 + ld h,a ;IF DISP_HIRES ; and $18 ; cp $18 ;ELSE - cp $58 + cp $58 ;ENDIF - ccf - ret + ccf + ret + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelUp.asm" ; @@ -566,32 +586,34 @@ SP.PixelDown: ; exit : Carry = moved off screen ; HL = moves one pixel up ; used : AF, HL + push namespace core SP.PixelUp: - ld a,h - dec h - and $07 - ret nz - ex af, af' - scf - ex af, af' - ld a,$08 - add a,h - ld h,a - ld a,l - sub $20 - ld l,a - ret nc - ld a,h - sub $08 - ld h,a + ld a,h + dec h + and $07 + ret nz + ex af, af' + scf + ex af, af' + ld a,$08 + add a,h + ld h,a + ld a,l + sub $20 + ld l,a + ret nc + ld a,h + sub $08 + ld h,a ;IF DISP_HIRES ; and $18 ; cp $18 ; ccf ;ELSE - cp $40 + cp $40 ;ENDIF - ret + ret + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelLeft.asm" ; @@ -610,6 +632,7 @@ SP.PixelUp: ; HL = moves one character left, if needed ; A = Bit Set with new pixel pos. ; used : AF, HL + push namespace core SP.PixelLeft: rlca ; Sets new pixel bit 1 to the right ret nc @@ -621,6 +644,7 @@ SP.PixelLeft: ccf ld a, 1 ret + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelRight.asm" ; @@ -639,6 +663,7 @@ SP.PixelLeft: ; HL = moves one character left, if needed ; A = Bit Set with new pixel pos. ; used : AF, HL + push namespace core SP.PixelRight: rrca ; Sets new pixel bit 1 to the right ret nc @@ -650,8 +675,10 @@ SP.PixelRight: ccf ld a, 80h ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/draw.asm" ;; DRAW PROCEDURE + push namespace core PROC LOCAL __DRAW1 LOCAL __DRAW2 @@ -732,10 +759,10 @@ __PIXEL_MASK: ld b, d ; Restores B' from D' pop de ; D'E' = y2, x2 exx ; At this point: D'E' = y2,x2 coords - ; B'C' = y1, y1 coords + ; B'C' = y1, y1 coords ex af, af' ; Saves A reg for later - ; A' = Pixel mask - ; H'L' = Screen Address of pixel + ; A' = Pixel mask + ; H'L' = Screen Address of pixel ld bc, (COORDS) ; B,C = y1, x1 ld a, e sub c ; dx = X2 - X1 @@ -888,7 +915,7 @@ __PLOTINVERSE: nop ; Replace with CPL if INVERSE 1 __PLOTOVER: or (hl) ; Replace with XOR (hl) if OVER 1 AND INVERSE 0 - ; Replace with AND (hl) if INVERSE 1 + ; Replace with AND (hl) if INVERSE 1 ld (hl), a ex af, af' ; Recovers flag. If Carry set => update ATTR ld a, e ; Recovers A reg @@ -907,150 +934,159 @@ __FASTPLOTEND: ld a, e ret ENDP + pop namespace #line 44 "inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 45 "inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 46 "inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 47 "inktemp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 48 "inktemp.bas" END diff --git a/tests/functional/label_sent.asm b/tests/functional/label_sent.asm index b8253b6f4..2661ea086 100644 --- a/tests/functional/label_sent.asm +++ b/tests/functional/label_sent.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__0: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/label_sent1.asm b/tests/functional/label_sent1.asm index fd9947c4a..b0a4cc934 100644 --- a/tests/functional/label_sent1.asm +++ b/tests/functional/label_sent1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__0: __LABEL__10: ld a, 1 - call BORDER + call core.BORDER ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,7 +42,9 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/border.asm" ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core BORDER EQU 229Bh + pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) #line 21 "label_sent1.bas" END diff --git a/tests/functional/label_sent2.asm b/tests/functional/label_sent2.asm index 98104b3bf..c591842df 100644 --- a/tests/functional/label_sent2.asm +++ b/tests/functional/label_sent2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__0: __LABEL__10: ld a, 1 - call BORDER + call core.BORDER ld a, 1 - call PAPER - call COPY_ATTR + call core.PAPER + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,13 +45,16 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/border.asm" ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core BORDER EQU 229Bh + pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) #line 24 "label_sent2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -59,70 +62,75 @@ __END_PROGRAM: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 25 "label_sent2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 26 "label_sent2.bas" END diff --git a/tests/functional/label_sent3.asm b/tests/functional/label_sent3.asm index 7fd8db740..d15027300 100644 --- a/tests/functional/label_sent3.asm +++ b/tests/functional/label_sent3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__0: __LABEL__10: ld a, 1 - call BORDER + call core.BORDER ld a, 1 - call PAPER - call COPY_ATTR + call core.PAPER + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,13 +45,16 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/border.asm" ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core BORDER EQU 229Bh + pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) #line 24 "label_sent3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -59,70 +62,75 @@ __END_PROGRAM: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 25 "label_sent3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 26 "label_sent3.bas" END diff --git a/tests/functional/label_sent4.asm b/tests/functional/label_sent4.asm index a71b5d76e..449920280 100644 --- a/tests/functional/label_sent4.asm +++ b/tests/functional/label_sent4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__0: __LABEL__10: ld a, 1 - call BORDER + call core.BORDER ld a, 1 - call PAPER - call COPY_ATTR + call core.PAPER + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,13 +45,16 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/border.asm" ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core BORDER EQU 229Bh + pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) #line 24 "label_sent4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -59,70 +62,75 @@ __END_PROGRAM: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 25 "label_sent4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 26 "label_sent4.bas" END diff --git a/tests/functional/label_sent5.asm b/tests/functional/label_sent5.asm index bdd689a8b..eed788fe4 100644 --- a/tests/functional/label_sent5.asm +++ b/tests/functional/label_sent5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__0: __LABEL__10: ld a, 1 - call BORDER + call core.BORDER ld a, 1 - call PAPER - call COPY_ATTR + call core.PAPER + call core.COPY_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,13 +45,16 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/border.asm" ; __FASTCALL__ Routine to change de border ; Parameter (color) specified in A register + push namespace core BORDER EQU 229Bh + pop namespace ; Nothing to do! (Directly from the ZX Spectrum ROM) #line 24 "label_sent5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -59,70 +62,75 @@ __END_PROGRAM: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 25 "label_sent5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 26 "label_sent5.bas" END diff --git a/tests/functional/labeldecl.asm b/tests/functional/labeldecl.asm index c176d3c85..8ef4a7f83 100644 --- a/tests/functional/labeldecl.asm +++ b/tests/functional/labeldecl.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 _c: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL__20: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/labelsent.asm b/tests/functional/labelsent.asm index 467cb27da..be9a78016 100644 --- a/tests/functional/labelsent.asm +++ b/tests/functional/labelsent.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,45 +8,45 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: ld hl, _a + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __ADDF + call core.__ADDF ld hl, _a - call __STOREF + call core.__STOREF ld hl, _b + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __ADDF + call core.__ADDF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -61,12 +61,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -81,19 +82,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -103,19 +105,22 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 34 "labelsent.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -136,32 +141,35 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 35 "labelsent.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 36 "labelsent.bas" END diff --git a/tests/functional/lbound0.asm b/tests/functional/lbound0.asm index 89cb7b5be..2b0bbe75f 100644 --- a/tests/functional/lbound0.asm +++ b/tests/functional/lbound0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -38,16 +38,16 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/lbound1.asm b/tests/functional/lbound1.asm index 89cb7b5be..2b0bbe75f 100644 --- a/tests/functional/lbound1.asm +++ b/tests/functional/lbound1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -38,16 +38,16 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/lbound10.asm b/tests/functional/lbound10.asm index 17d1f7290..fd8b083ee 100644 --- a/tests/functional/lbound10.asm +++ b/tests/functional/lbound10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test3 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,7 +56,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -97,7 +97,7 @@ _test3: ld hl, -8 ld de, __LABEL5 ld bc, 9 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS push ix pop hl ld de, -8 @@ -109,7 +109,7 @@ _test3__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -194,6 +194,7 @@ _test3.a.__LBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -223,6 +224,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -288,9 +290,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -298,37 +301,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -341,90 +345,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -438,25 +444,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -471,6 +479,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -577,7 +586,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 92 "lbound10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -591,6 +601,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -651,6 +662,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 93 "lbound10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -720,94 +732,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 94 "lbound10.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/lbound11.asm b/tests/functional/lbound11.asm index 24eaa68f6..341473eb2 100644 --- a/tests/functional/lbound11.asm +++ b/tests/functional/lbound11.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test3 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -72,7 +72,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -113,7 +113,7 @@ _test3: ld hl, -8 ld de, __LABEL5 ld bc, 9 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS push ix pop hl ld de, -8 @@ -125,7 +125,7 @@ _test3__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -210,6 +210,7 @@ _test3.a.__LBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -239,6 +240,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -304,9 +306,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -314,37 +317,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -357,90 +361,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -454,25 +460,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -487,6 +495,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -593,7 +602,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 108 "lbound11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -607,6 +617,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -667,6 +678,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 109 "lbound11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -736,94 +748,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 110 "lbound11.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/lbound12.asm b/tests/functional/lbound12.asm index 559fa13a9..1353c559b 100644 --- a/tests/functional/lbound12.asm +++ b/tests/functional/lbound12.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test1 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,7 +56,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -97,7 +97,7 @@ _test1: ld hl, -8 ld de, __LABEL5 ld bc, 18 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS push ix pop hl ld de, -8 @@ -111,7 +111,7 @@ _test1__leave: push hl ld l, (ix-6) ld h, (ix-5) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -212,6 +212,7 @@ _test2__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -241,6 +242,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -306,9 +308,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -316,37 +319,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -359,90 +363,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -456,25 +462,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -489,6 +497,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -595,7 +604,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 110 "lbound12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -669,134 +679,138 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 111 "lbound12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -810,6 +824,7 @@ __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -870,6 +885,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 112 "lbound12.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/lbound13.asm b/tests/functional/lbound13.asm index 2f579633f..d1c4ff7a0 100644 --- a/tests/functional/lbound13.asm +++ b/tests/functional/lbound13.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00 _x: @@ -39,8 +39,8 @@ _x.__LBOUND__: DEFW 0000h _x.__UBOUND__: DEFW 0004h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _x push hl call _maxValue @@ -48,9 +48,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -71,7 +71,7 @@ _maxValue: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (ix-3), l ld (ix-2), h jp __LABEL0 @@ -85,7 +85,7 @@ __LABEL3: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR pop af cp (hl) jp nc, __LABEL6 @@ -96,7 +96,7 @@ __LABEL3: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld a, (hl) ld (ix-1), a __LABEL6: @@ -114,7 +114,7 @@ __LABEL0: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND pop de or a sbc hl, de @@ -147,81 +147,84 @@ _maxValue__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -229,16 +232,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -257,7 +260,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 91 "lbound13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -271,6 +275,7 @@ TMP_ARR_PTR: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -331,5 +336,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 92 "lbound13.bas" END diff --git a/tests/functional/lbound2.asm b/tests/functional/lbound2.asm index 3a5f949af..0a7a17778 100644 --- a/tests/functional/lbound2.asm +++ b/tests/functional/lbound2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00h DEFB 00h @@ -46,19 +46,19 @@ __LABEL0: _a.__LBOUND__: DEFW 0003h DEFW 0007h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,6 +80,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -140,5 +141,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 22 "lbound2.bas" END diff --git a/tests/functional/lbound3.asm b/tests/functional/lbound3.asm index 7cac19df5..d560d4db6 100644 --- a/tests/functional/lbound3.asm +++ b/tests/functional/lbound3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a: @@ -38,16 +38,16 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 3 ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/lbound4.asm b/tests/functional/lbound4.asm index 0abf4427d..60dfc12ad 100644 --- a/tests/functional/lbound4.asm +++ b/tests/functional/lbound4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 01h DEFB 00h @@ -46,19 +46,19 @@ __LABEL0: _a.__LBOUND__: DEFW 0003h DEFW 0007h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,6 +80,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -140,5 +141,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 22 "lbound4.bas" END diff --git a/tests/functional/lbound5.asm b/tests/functional/lbound5.asm index 1820b20ef..5a5a9ce9f 100644 --- a/tests/functional/lbound5.asm +++ b/tests/functional/lbound5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 02h DEFB 00h @@ -46,19 +46,19 @@ __LABEL0: _a.__LBOUND__: DEFW 0003h DEFW 0007h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,6 +80,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -140,5 +141,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 22 "lbound5.bas" END diff --git a/tests/functional/lbound6.asm b/tests/functional/lbound6.asm index 964b7dec4..3efd29406 100644 --- a/tests/functional/lbound6.asm +++ b/tests/functional/lbound6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,7 +64,7 @@ _test: ld hl, -8 ld de, __LABEL5 ld bc, 9 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS ld hl, 0 ld (_b), hl jp __LABEL0 @@ -75,7 +75,7 @@ __LABEL3: pop hl ld de, -8 add hl, de - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -93,7 +93,7 @@ _test__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -178,6 +178,7 @@ _test.a.__LBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -207,6 +208,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -272,9 +274,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -282,37 +285,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -325,90 +329,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -422,25 +428,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -455,6 +463,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -561,7 +570,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 76 "lbound6.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -575,6 +585,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -635,6 +646,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 77 "lbound6.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -704,94 +716,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 78 "lbound6.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/lbound7.asm b/tests/functional/lbound7.asm index 22cbb3a4f..2bb54a0ea 100644 --- a/tests/functional/lbound7.asm +++ b/tests/functional/lbound7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -45,22 +45,22 @@ __LABEL5: _a.__LBOUND__: DEFW 0003h DEFW 0007h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _test ld hl, (_b) push hl ld hl, _a - call __LBOUND + call core.__LBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -81,7 +81,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -115,6 +115,7 @@ _test__leave: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -175,5 +176,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 58 "lbound7.bas" END diff --git a/tests/functional/lbound8.asm b/tests/functional/lbound8.asm index 9c998e7cd..410a31706 100644 --- a/tests/functional/lbound8.asm +++ b/tests/functional/lbound8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -45,17 +45,17 @@ __LABEL5: _a.__LBOUND__: DEFW 0003h DEFW 0007h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,7 +76,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -110,6 +110,7 @@ _test__leave: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -170,5 +171,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 53 "lbound8.bas" END diff --git a/tests/functional/lbound9.asm b/tests/functional/lbound9.asm index 93c12c025..183b17eae 100644 --- a/tests/functional/lbound9.asm +++ b/tests/functional/lbound9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -45,17 +45,17 @@ __LABEL5: _a.__LBOUND__: DEFW 0003h DEFW 0007h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _test2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -92,7 +92,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __LBOUND + call core.__LBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -126,6 +126,7 @@ _test1__leave: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -186,5 +187,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 69 "lbound9.bas" END diff --git a/tests/functional/lcd3.asm b/tests/functional/lcd3.asm index 28e9f2828..c724cd606 100644 --- a/tests/functional/lcd3.asm +++ b/tests/functional/lcd3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,90 +8,90 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _adr: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a push af ld a, 30 - call PRINT_AT + call core.PRINT_AT ld hl, __LABEL0 xor a - call __PRINTSTR + call core.__PRINTSTR ld a, 1 push af ld a, 30 - call PRINT_AT + call core.PRINT_AT ld a, 2 push af ld hl, __LABEL1 - call __LOADSTR + call core.__LOADSTR push hl ld a, (_adr) ld de, (_adr + 1) ld bc, (_adr + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, (hl) - call __U8TOFREG - call __STR_FAST + call core.__U8TOFREG + call core.__STR_FAST push hl call _lset ld a, 1 - call __PRINTSTR + call core.__PRINTSTR ld a, 2 push af ld a, 30 - call PRINT_AT + call core.PRINT_AT ld hl, __LABEL2 xor a - call __PRINTSTR + call core.__PRINTSTR ld a, 3 push af ld a, 30 - call PRINT_AT + call core.PRINT_AT ld a, 2 push af ld hl, __LABEL1 - call __LOADSTR + call core.__LOADSTR push hl ld hl, _adr + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 082h ld de, 00040h ld bc, 00000h - call __ADDF - call __FTOU32REG + call core.__ADDF + call core.__FTOU32REG ld a, (hl) - call __U8TOFREG - call __STR_FAST + call core.__U8TOFREG + call core.__STR_FAST push hl call _lset ld a, 1 - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -107,7 +107,7 @@ _lset: __LABEL3: ld l, (ix+4) ld h, (ix+5) - call __STRLEN + call core.__STRLEN push hl ld a, (ix+9) ld l, a @@ -124,25 +124,25 @@ __LABEL3: ld h, (ix+5) ex de, hl pop hl - call __ADDSTR + call core.__ADDSTR ld d, h ld e, l ld bc, 4 - call __PSTORE_STR2 + call core.__PSTORE_STR2 jp __LABEL3 __LABEL4: ld l, (ix+4) ld h, (ix+5) - call __LOADSTR + call core.__LOADSTR _lset__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix+6) ld h, (ix+7) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -171,12 +171,13 @@ __LABEL2: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -191,19 +192,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -213,13 +215,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 140 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -345,9 +349,10 @@ __ADDF: ; Addition ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -355,37 +360,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -395,168 +401,173 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 141 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -573,11 +584,12 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 142 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -643,6 +655,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -672,6 +685,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -684,125 +698,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 143 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -811,109 +829,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -921,319 +948,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1288,464 +1335,469 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 144 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 145 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" ; vim:ts=4:et:sw=4 @@ -1761,42 +1813,47 @@ __PRINT_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" + push namespace core __PSTORE_STR2: push ix pop hl add hl, bc jp __STORE_STR2 + pop namespace #line 146 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -1817,238 +1874,247 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 147 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation ; Given a FP number in C ED LH ; Returns a pointer (in HL) to the memory heap ; containing the FP number string representation + push namespace core __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - push bc - push de - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - pop de - pop bc - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - ex de, hl ; HL = start of original string - ldir ; Copies string content - pop de ; Original (ROM-CALC) string - pop bc ; Original Length + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + push bc + push de + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + pop de + pop bc + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + ex de, hl ; HL = start of original string + ldir ; Copies string content + pop de ; Original (ROM-CALC) string + pop bc ; Original Length __STR_END: - ex de, hl - inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result - ret + ex de, hl + inc bc + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + pop namespace #line 148 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 149 "lcd3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 151 "lcd3.bas" END diff --git a/tests/functional/lcd5.asm b/tests/functional/lcd5.asm index 98b4fc661..7eb1d42f0 100644 --- a/tests/functional/lcd5.asm +++ b/tests/functional/lcd5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _tile: DEFW __LABEL0 _tile.__DATA__.__PTR__: @@ -62,14 +62,14 @@ _tile.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/lcd6.asm b/tests/functional/lcd6.asm index 937aba7e6..e7d13958a 100644 --- a/tests/functional/lcd6.asm +++ b/tests/functional/lcd6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _tile: DEFW __LABEL1 _tile.__DATA__.__PTR__: @@ -67,14 +67,14 @@ _tile.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -93,13 +93,13 @@ _SubLifetime: ld hl, -4 ld de, __LABEL0 ld bc, 18 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY _SubLifetime__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -187,6 +187,7 @@ _SubLifetime__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -216,6 +217,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -281,9 +283,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -291,37 +294,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -334,90 +338,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -431,25 +437,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -464,6 +472,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -513,7 +522,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 45 "lcd6.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -583,94 +593,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 46 "lcd6.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/lcd7.asm b/tests/functional/lcd7.asm index 62408a346..2dd187d96 100644 --- a/tests/functional/lcd7.asm +++ b/tests/functional/lcd7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _Frame ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,14 +48,14 @@ _printerPutString: ld l, (ix+4) ld h, (ix+5) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _printerPutString__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -73,10 +73,10 @@ _Frame: push hl ld de, __LABEL0 ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-2) ld h, (ix-1) - call __LOADSTR + call core.__LOADSTR push hl call _printerPutString _Frame__leave: @@ -84,7 +84,7 @@ _Frame__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -219,9 +219,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -229,37 +230,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -269,94 +271,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 71 "lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -422,6 +426,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -451,6 +456,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -463,125 +469,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 72 "lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -593,109 +603,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -703,319 +722,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1070,468 +1109,475 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 73 "lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 74 "lcd7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -1631,132 +1677,137 @@ __PRINT_STR: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1781,11 +1832,14 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 75 "lcd7.bas" END diff --git a/tests/functional/lcd8.asm b/tests/functional/lcd8.asm index 782f4c590..466dcf996 100644 --- a/tests/functional/lcd8.asm +++ b/tests/functional/lcd8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _Frame ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,14 +51,14 @@ _printerPutString: ld l, (ix+4) ld h, (ix+5) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _printerPutString__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -74,7 +74,7 @@ _Frame: add ix, sp ld l, (ix+4) ld h, (ix+5) - call __LOADSTR + call core.__LOADSTR push hl call _printerPutString _Frame__leave: @@ -82,7 +82,7 @@ _Frame__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -221,9 +221,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -231,37 +232,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -271,94 +273,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 73 "lcd8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -424,6 +428,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -453,6 +458,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -465,125 +471,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 74 "lcd8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -595,109 +605,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -705,319 +724,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1072,467 +1111,474 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 75 "lcd8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 76 "lcd8.bas" END diff --git a/tests/functional/lcd9.asm b/tests/functional/lcd9.asm index 118d1e2ac..013071ca2 100644 --- a/tests/functional/lcd9.asm +++ b/tests/functional/lcd9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _strg: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _strg - call __STORE_STR + call core.__STORE_STR call _Frame ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,14 +53,14 @@ _printerPutString: ld l, (ix+4) ld h, (ix+5) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _printerPutString__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -75,7 +75,7 @@ _Frame: ld ix, 0 add ix, sp ld hl, (_strg) - call __LOADSTR + call core.__LOADSTR push hl call _printerPutString _Frame__leave: @@ -211,9 +211,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -221,37 +222,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -261,94 +263,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 61 "lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -414,6 +418,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -443,6 +448,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -455,125 +461,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 62 "lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -585,109 +595,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -695,319 +714,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1062,468 +1101,475 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 63 "lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 64 "lcd9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -1617,132 +1663,137 @@ __PRINT_STR: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1767,5 +1818,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 65 "lcd9.bas" END diff --git a/tests/functional/lcd_crash.asm b/tests/functional/lcd_crash.asm index 2da04c8bc..e4a6172b1 100644 --- a/tests/functional/lcd_crash.asm +++ b/tests/functional/lcd_crash.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _monsterx: DEFB 00 _tiles: @@ -62,8 +62,8 @@ _tiles.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL__void ld (_tiles.__DATA__ + 0), hl ld (_tiles.__DATA__ + 2), hl @@ -78,9 +78,9 @@ __LABEL__void: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -117,7 +117,7 @@ _settile: push af ld a, (_monsterx) ld h, 3 - call __MUL8_FAST + call core.__MUL8_FAST ld l, a add a, a sbc a, a @@ -125,7 +125,7 @@ _settile: push hl ld a, (_monsterx) ld h, 3 - call __MUL8_FAST + call core.__MUL8_FAST ld l, a add a, a sbc a, a @@ -144,14 +144,15 @@ _settile__leave: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -185,7 +186,8 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 81 "lcd_crash.bas" END diff --git a/tests/functional/lef16.asm b/tests/functional/lef16.asm index 434584fd9..74a44b374 100644 --- a/tests/functional/lef16.asm +++ b/tests/functional/lef16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LEI32 + call core.__SWAP32 + call core.__LEI32 ld l, a ld h, 0 ex de, hl @@ -52,7 +52,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ex de, hl @@ -65,7 +65,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ex de, hl @@ -78,7 +78,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ex de, hl @@ -88,9 +88,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -106,26 +106,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lei32.asm" + push namespace core __LEI32: ; Test 32 bit values Top of the stack <= HL,DE PROC LOCAL checkParity @@ -153,12 +156,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 70 "lef16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -168,6 +173,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 71 "lef16.bas" END diff --git a/tests/functional/lei32.asm b/tests/functional/lei32.asm index b2ff3ee9b..00c3ad1d3 100644 --- a/tests/functional/lei32.asm +++ b/tests/functional/lei32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LEI32 + call core.__SWAP32 + call core.__LEI32 ld l, a ld h, 0 ld e, h @@ -52,7 +52,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ld e, h @@ -65,7 +65,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ld e, h @@ -78,7 +78,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ld e, h @@ -91,7 +91,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __LEI32 + call core.__LEI32 ld l, a ld h, 0 ld e, h @@ -101,9 +101,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -119,26 +119,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lei32.asm" + push namespace core __LEI32: ; Test 32 bit values Top of the stack <= HL,DE PROC LOCAL checkParity @@ -166,12 +169,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 83 "lei32.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -181,6 +186,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 84 "lei32.bas" END diff --git a/tests/functional/lei8.asm b/tests/functional/lei8.asm index cb890143c..72463d27d 100644 --- a/tests/functional/lei8.asm +++ b/tests/functional/lei8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,54 +8,54 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h _le: DEFB 00h _l: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_level) ld h, a ld a, (_le) - call __LEI8 + call core.__LEI8 ld (_l), a ld hl, (_level - 1) ld a, (_le) - call __LEI8 + call core.__LEI8 ld (_l), a ld a, (_le) push af ld hl, (_level - 1) pop af - call __LEI8 + call core.__LEI8 ld (_l), a ld a, (_le) ld hl, (_level - 1) - call __LEI8 + call core.__LEI8 ld (_l), a ld a, (_level) ld h, a xor a - call __LEI8 + call core.__LEI8 ld (_l), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -66,8 +66,9 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -85,5 +86,6 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 41 "lei8.bas" END diff --git a/tests/functional/let0.asm b/tests/functional/let0.asm index cf0978984..73ef03038 100644 --- a/tests/functional/let0.asm +++ b/tests/functional/let0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 2 ld (_a), a inc a @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/let_array_substr.asm b/tests/functional/let_array_substr.asm index 8297a305b..cb01fd311 100644 --- a/tests/functional/let_array_substr.asm +++ b/tests/functional/let_array_substr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 03h DEFB 00h @@ -56,14 +56,14 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -75,18 +75,18 @@ __MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) ex de, hl - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -132,81 +132,84 @@ __LABEL1: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -214,16 +217,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -242,7 +245,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 59 "let_array_substr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" @@ -377,9 +381,10 @@ TMP_ARR_PTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -387,37 +392,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -427,204 +433,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 60 "let_array_substr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -701,6 +711,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -730,6 +741,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -802,90 +814,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -907,132 +921,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1057,5 +1076,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 61 "let_array_substr.bas" END diff --git a/tests/functional/let_array_substr1.asm b/tests/functional/let_array_substr1.asm index c25a0d1d3..185aea918 100644 --- a/tests/functional/let_array_substr1.asm +++ b/tests/functional/let_array_substr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 03h DEFB 00h @@ -56,14 +56,14 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -75,18 +75,18 @@ __MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) ex de, hl - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -132,81 +132,84 @@ __LABEL1: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -214,16 +217,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -242,7 +245,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 59 "let_array_substr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" @@ -377,9 +381,10 @@ TMP_ARR_PTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -387,37 +392,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -427,204 +433,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 60 "let_array_substr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -701,6 +711,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -730,6 +741,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -802,90 +814,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -907,132 +921,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1057,5 +1076,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 61 "let_array_substr1.bas" END diff --git a/tests/functional/let_array_substr10.asm b/tests/functional/let_array_substr10.asm index dcce41a44..efae17190 100644 --- a/tests/functional/let_array_substr10.asm +++ b/tests/functional/let_array_substr10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 8 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 3 push hl ld hl, (_a.__DATA__ + 8) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr10.bas" END diff --git a/tests/functional/let_array_substr11.asm b/tests/functional/let_array_substr11.asm index 7801ff8f8..fbed91b6e 100644 --- a/tests/functional/let_array_substr11.asm +++ b/tests/functional/let_array_substr11.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 65534 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr11.bas" END diff --git a/tests/functional/let_array_substr12.asm b/tests/functional/let_array_substr12.asm index 6c4919df6..136ca83b8 100644 --- a/tests/functional/let_array_substr12.asm +++ b/tests/functional/let_array_substr12.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 5 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr12.bas" END diff --git a/tests/functional/let_array_substr13.asm b/tests/functional/let_array_substr13.asm index c29891f2b..1b46fc148 100644 --- a/tests/functional/let_array_substr13.asm +++ b/tests/functional/let_array_substr13.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 5 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr13.bas" END diff --git a/tests/functional/let_array_substr2.asm b/tests/functional/let_array_substr2.asm index 5095e071a..3cbca2524 100644 --- a/tests/functional/let_array_substr2.asm +++ b/tests/functional/let_array_substr2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 5 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr2.bas" END diff --git a/tests/functional/let_array_substr3.asm b/tests/functional/let_array_substr3.asm index 1beb3d635..bb444aa25 100644 --- a/tests/functional/let_array_substr3.asm +++ b/tests/functional/let_array_substr3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 5 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr3.bas" END diff --git a/tests/functional/let_array_substr5.asm b/tests/functional/let_array_substr5.asm index 9f7c63464..6cd4247eb 100644 --- a/tests/functional/let_array_substr5.asm +++ b/tests/functional/let_array_substr5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 03h DEFB 00h @@ -56,14 +56,14 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -75,18 +75,18 @@ __MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) ex de, hl - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -132,81 +132,84 @@ __LABEL1: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -214,16 +217,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -242,7 +245,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 59 "let_array_substr5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" @@ -377,9 +381,10 @@ TMP_ARR_PTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -387,37 +392,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -427,204 +433,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 60 "let_array_substr5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -701,6 +711,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -730,6 +741,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -802,90 +814,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -907,132 +921,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1057,5 +1076,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 61 "let_array_substr5.bas" END diff --git a/tests/functional/let_array_substr7.asm b/tests/functional/let_array_substr7.asm index e81c9a15a..6cd6b7285 100644 --- a/tests/functional/let_array_substr7.asm +++ b/tests/functional/let_array_substr7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr7.bas" END diff --git a/tests/functional/let_array_substr9.asm b/tests/functional/let_array_substr9.asm index aae95a798..5c0c685e1 100644 --- a/tests/functional/let_array_substr9.asm +++ b/tests/functional/let_array_substr9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -53,11 +53,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 6 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -67,13 +67,13 @@ __MAIN_PROGRAM__: ld hl, 65534 push hl ld hl, (_a.__DATA__ + 6) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -235,9 +235,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +246,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -285,204 +287,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 49 "let_array_substr9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -559,6 +565,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -588,6 +595,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -660,90 +668,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -765,132 +775,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -915,5 +930,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 50 "let_array_substr9.bas" END diff --git a/tests/functional/letarrstr_substr0.asm b/tests/functional/letarrstr_substr0.asm index e5b68c5de..29c14c32c 100644 --- a/tests/functional/letarrstr_substr0.asm +++ b/tests/functional/letarrstr_substr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -45,26 +45,26 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a.__DATA__ + 2) - call __LOADSTR + call core.__LOADSTR push hl ld hl, 2 push hl ld hl, 4 push hl ld a, 1 - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -138,6 +138,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -167,6 +168,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -232,9 +234,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -242,37 +245,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -285,125 +289,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 29 "letarrstr_substr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -480,119 +488,123 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 30 "letarrstr_substr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -612,84 +624,88 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 31 "letarrstr_substr0.bas" END diff --git a/tests/functional/letarrstr_substr1.asm b/tests/functional/letarrstr_substr1.asm index 76f1c4931..6b4641507 100644 --- a/tests/functional/letarrstr_substr1.asm +++ b/tests/functional/letarrstr_substr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -45,26 +45,26 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a.__DATA__ + 2) - call __LOADSTR + call core.__LOADSTR push hl ld hl, 2 push hl ld hl, 2 push hl ld a, 1 - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -138,6 +138,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -167,6 +168,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -232,9 +234,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -242,37 +245,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -285,125 +289,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 29 "letarrstr_substr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -480,119 +488,123 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 30 "letarrstr_substr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -612,84 +624,88 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 31 "letarrstr_substr1.bas" END diff --git a/tests/functional/letsubstr_local.asm b/tests/functional/letsubstr_local.asm index 4f9719a0c..945da713b 100644 --- a/tests/functional/letsubstr_local.asm +++ b/tests/functional/letsubstr_local.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,40 +8,40 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 1 push hl call _editStringFN ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -69,19 +69,19 @@ _editStringFN: push hl ld l, (ix-2) ld h, (ix-1) - call __LETSUBSTR + call core.__LETSUBSTR ld l, (ix-2) ld h, (ix-1) - call __LOADSTR + call core.__LOADSTR _editStringFN__leave: ex af, af' exx ld l, (ix+6) ld h, (ix+7) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -220,9 +220,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -230,37 +231,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -270,94 +272,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 71 "letsubstr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" @@ -368,115 +372,117 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; A Register => 0 if HL is not freed from memory ; => Not 0 if HL must be freed from memory on exit ; TOP -3 B$ address + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 72 "letsubstr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -542,6 +548,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -571,6 +578,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -583,125 +591,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 73 "letsubstr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -710,29 +722,31 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 74 "letsubstr_local.bas" END diff --git a/tests/functional/letsubstr_param_byref.asm b/tests/functional/letsubstr_param_byref.asm index 13f144134..daad7949d 100644 --- a/tests/functional/letsubstr_param_byref.asm +++ b/tests/functional/letsubstr_param_byref.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 1 push hl @@ -37,13 +37,13 @@ __MAIN_PROGRAM__: call _editStringFN ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -73,20 +73,20 @@ _editStringFN: inc hl ld h, (hl) ld l, a - call __LETSUBSTR + call core.__LETSUBSTR ld h, (ix+5) ld l, (ix+4) ld c, (hl) inc hl ld h, (hl) ld l, c - call __LOADSTR + call core.__LOADSTR _editStringFN__leave: ex af, af' exx ld l, (ix+8) ld h, (ix+9) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -226,9 +226,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -236,37 +237,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -276,94 +278,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 77 "letsubstr_param_byref.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" @@ -374,115 +378,117 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; A Register => 0 if HL is not freed from memory ; => Not 0 if HL must be freed from memory on exit ; TOP -3 B$ address + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 78 "letsubstr_param_byref.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -548,6 +554,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -577,6 +584,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -589,125 +597,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 79 "letsubstr_param_byref.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -716,29 +728,31 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 80 "letsubstr_param_byref.bas" END diff --git a/tests/functional/letsubstr_param_byval.asm b/tests/functional/letsubstr_param_byval.asm index 1924c9316..96dfa91c4 100644 --- a/tests/functional/letsubstr_param_byval.asm +++ b/tests/functional/letsubstr_param_byval.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,43 +8,43 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 1 push hl ld hl, (_a) - call __LOADSTR + call core.__LOADSTR push hl call _editStringFN ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -70,19 +70,19 @@ _editStringFN: push hl ld l, (ix+4) ld h, (ix+5) - call __LETSUBSTR + call core.__LETSUBSTR ld l, (ix+4) ld h, (ix+5) - call __LOADSTR + call core.__LOADSTR _editStringFN__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix+8) ld h, (ix+9) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -222,9 +222,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -232,37 +233,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -272,94 +274,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 73 "letsubstr_param_byval.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" ; Substring assigment eg. LET a$(p0 TO p1) = "xxxx" @@ -370,115 +374,117 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; A Register => 0 if HL is not freed from memory ; => Not 0 if HL must be freed from memory on exit ; TOP -3 B$ address + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 74 "letsubstr_param_byval.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -544,6 +550,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -573,6 +580,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -585,125 +593,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 75 "letsubstr_param_byval.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -712,29 +724,31 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 76 "letsubstr_param_byval.bas" END diff --git a/tests/functional/leu32.asm b/tests/functional/leu32.asm index b33e165f8..a4a32b5dc 100644 --- a/tests/functional/leu32.asm +++ b/tests/functional/leu32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,15 +30,15 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 + call core.__SWAP32 pop bc or a sbc hl, bc @@ -134,9 +134,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -149,8 +149,9 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -160,6 +161,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 116 "leu32.bas" END diff --git a/tests/functional/line_macro.asm b/tests/functional/line_macro.asm index 75e043f44..9f9969f60 100644 --- a/tests/functional/line_macro.asm +++ b/tests/functional/line_macro.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 5 ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/llc.asm b/tests/functional/llc.asm index 1fe3ca8ed..d6f4398fd 100644 --- a/tests/functional/llc.asm +++ b/tests/functional/llc.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _r: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl xor a @@ -36,13 +36,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_r) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -188,9 +188,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -198,37 +199,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -238,203 +240,207 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 30 "llc.bas" END diff --git a/tests/functional/load02.asm b/tests/functional/load02.asm index 21fcac011..182064241 100644 --- a/tests/functional/load02.asm +++ b/tests/functional/load02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _variableToSave: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, _variableToSave push hl @@ -37,13 +37,13 @@ __MAIN_PROGRAM__: push hl ld a, 1 push af - call LOAD_CODE + call core.LOAD_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -185,9 +185,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -195,37 +196,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -235,94 +237,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -331,70 +335,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -424,49 +433,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -474,296 +489,316 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -818,424 +853,428 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 6 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + push namespace core LOAD_CODE: ; This function will implement the LOAD CODE Routine ; Parameters in the stack are HL => String with LOAD name @@ -1258,11 +1297,11 @@ LOAD_CODE: LOCAL TMP_SP MEM0 EQU 5C92h ; Temporary memory buffer HEAD1 EQU MEM0 + 8 ; Uses CALC Mem for temporary storage - ; Must skip first 8 bytes used by - ; PRINT routine + ; Must skip first 8 bytes used by + ; PRINT routine TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage TMP_SP EQU TMP_HEADER + 2 ; Temporary SP storage -#line 40 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 42 "/zxbasic/src/arch/zx48k/library-asm/load.asm" TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG pop hl ; Return address pop af ; A = 1 => LOAD; A = 0 => VERIFY @@ -1334,26 +1373,26 @@ LD_LOOK_H: xor a ; reset zero flag scf ; set carry flag call LD_BYTES ; routine LD-BYTES loads a header from tape - ; to second descriptor. + ; to second descriptor. pop ix ; restore IX jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found. ld c, 80h ; C has bit 7 set to indicate header type mismatch as - ; a default startpoint. + ; a default startpoint. ld a, (ix + 0) ; compare loaded type cp 3 ; with expected bytes header jr nz, LD_TYPE ; forward to LD-TYPE with mis-match. ld c, -10 ; set C to minus ten - will count characters - ; up to zero. + ; up to zero. LD_TYPE: cp 4 ; check if type in acceptable range 0 - 3. jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over. - ; else A indicates type 0-3. + ; else A indicates type 0-3. call PRINT_TAPE_MESSAGES; Print tape msg -#line 148 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 150 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld hl, HEAD1 + 1 ; point HL to 1st descriptor. ld de, (TMP_HEADER) ; point DE to 2nd descriptor. ld b, 10 ; the count will be ten characters for the - ; filename. + ; filename. ld a, (hl) ; fetch first character and test for inc a ; value 255. jr nz, LD_NAME ; forward to LD-NAME if not the wildcard. @@ -1376,14 +1415,14 @@ LD_NAME: ;; LD-CH-PR LD_CH_PR: call __PRINTCHAR ; PRINT-A prints character -#line 184 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 186 "/zxbasic/src/arch/zx48k/library-asm/load.asm" djnz LD_NAME ; loop back to LD-NAME for ten characters. bit 7, c ; test if all matched jr nz, LD_LOOK_H ; back to LD-LOOK-H if not ; else print a terminal carriage return. ld a, 0Dh ; prepare carriage return. call __PRINTCHAR ; PRINT-A outputs it. -#line 195 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 197 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld a, (HEAD1) cp 03 ; Only "bytes:" header is used un ZX BASIC jr nz, LD_LOOK_H @@ -1398,7 +1437,7 @@ VR_CONTROL: ld l, a or h ; check length of old for zero. (Carry reset) jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified - ; e.g. LOAD "x" CODE + ; e.g. LOAD "x" CODE sbc hl, de jr nz, LOAD_ERROR ; Lengths don't match VR_CONT_1: @@ -1449,7 +1488,7 @@ LD_BYTES_RET: LD_BYTES_NOINTER: ex af, af' ret -#line 278 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 280 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ENDP PRINT_TAPE_MESSAGES: PROC @@ -1473,11 +1512,11 @@ LOOK_NEXT_TAPE_MSG: inc hl ; Point to next char cp (hl) ; Is it 0Dh? jr nz, LOOK_NEXT_TAPE_MSG - ; Ok next message found + ; Ok next message found djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip PRINT_TAPE_MSG: - ; Ok. This will print bytes after (HL) - ; until one of them has bit 7 set + ; Ok. This will print bytes after (HL) + ; until one of them has bit 7 set ld a, (hl) and 7Fh ; Clear bit 7 of A call __PRINTCHAR @@ -1488,7 +1527,8 @@ PRINT_TAPE_MSG: pop bc ret ENDP -#line 332 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + pop namespace #line 34 "load02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -1562,124 +1602,128 @@ PRINT_TAPE_MSG: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 35 "load02.bas" END diff --git a/tests/functional/load03.asm b/tests/functional/load03.asm index 2af90d65d..a540a61af 100644 --- a/tests/functional/load03.asm +++ b/tests/functional/load03.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, __LABEL__.ZXBASIC_USER_DATA push hl @@ -35,13 +35,13 @@ __MAIN_PROGRAM__: push hl ld a, 1 push af - call LOAD_CODE + call core.LOAD_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -182,9 +182,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -192,37 +193,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -232,94 +234,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -328,70 +332,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -421,49 +430,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -471,296 +486,316 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) -#line 63 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" - ret #line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + ret +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -815,424 +850,428 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/load.asm" #line 6 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + push namespace core LOAD_CODE: ; This function will implement the LOAD CODE Routine ; Parameters in the stack are HL => String with LOAD name @@ -1255,11 +1294,11 @@ LOAD_CODE: LOCAL TMP_SP MEM0 EQU 5C92h ; Temporary memory buffer HEAD1 EQU MEM0 + 8 ; Uses CALC Mem for temporary storage - ; Must skip first 8 bytes used by - ; PRINT routine + ; Must skip first 8 bytes used by + ; PRINT routine TMP_HEADER EQU HEAD1 + 17 ; Temporary HEADER2 pointer storage TMP_SP EQU TMP_HEADER + 2 ; Temporary SP storage -#line 40 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 42 "/zxbasic/src/arch/zx48k/library-asm/load.asm" TMP_FLAG EQU 23655 ; Uses BREG as a Temporary FLAG pop hl ; Return address pop af ; A = 1 => LOAD; A = 0 => VERIFY @@ -1331,26 +1370,26 @@ LD_LOOK_H: xor a ; reset zero flag scf ; set carry flag call LD_BYTES ; routine LD-BYTES loads a header from tape - ; to second descriptor. + ; to second descriptor. pop ix ; restore IX jr nc, LD_LOOK_H ; loop back to LD-LOOK-H until header found. ld c, 80h ; C has bit 7 set to indicate header type mismatch as - ; a default startpoint. + ; a default startpoint. ld a, (ix + 0) ; compare loaded type cp 3 ; with expected bytes header jr nz, LD_TYPE ; forward to LD-TYPE with mis-match. ld c, -10 ; set C to minus ten - will count characters - ; up to zero. + ; up to zero. LD_TYPE: cp 4 ; check if type in acceptable range 0 - 3. jr nc, LD_LOOK_H ; back to LD-LOOK-H with 4 and over. - ; else A indicates type 0-3. + ; else A indicates type 0-3. call PRINT_TAPE_MESSAGES; Print tape msg -#line 148 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 150 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld hl, HEAD1 + 1 ; point HL to 1st descriptor. ld de, (TMP_HEADER) ; point DE to 2nd descriptor. ld b, 10 ; the count will be ten characters for the - ; filename. + ; filename. ld a, (hl) ; fetch first character and test for inc a ; value 255. jr nz, LD_NAME ; forward to LD-NAME if not the wildcard. @@ -1373,14 +1412,14 @@ LD_NAME: ;; LD-CH-PR LD_CH_PR: call __PRINTCHAR ; PRINT-A prints character -#line 184 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 186 "/zxbasic/src/arch/zx48k/library-asm/load.asm" djnz LD_NAME ; loop back to LD-NAME for ten characters. bit 7, c ; test if all matched jr nz, LD_LOOK_H ; back to LD-LOOK-H if not ; else print a terminal carriage return. ld a, 0Dh ; prepare carriage return. call __PRINTCHAR ; PRINT-A outputs it. -#line 195 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 197 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ld a, (HEAD1) cp 03 ; Only "bytes:" header is used un ZX BASIC jr nz, LD_LOOK_H @@ -1395,7 +1434,7 @@ VR_CONTROL: ld l, a or h ; check length of old for zero. (Carry reset) jr z, VR_CONT_1 ; forward to VR-CONT-1 if length unspecified - ; e.g. LOAD "x" CODE + ; e.g. LOAD "x" CODE sbc hl, de jr nz, LOAD_ERROR ; Lengths don't match VR_CONT_1: @@ -1446,7 +1485,7 @@ LD_BYTES_RET: LD_BYTES_NOINTER: ex af, af' ret -#line 278 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 280 "/zxbasic/src/arch/zx48k/library-asm/load.asm" ENDP PRINT_TAPE_MESSAGES: PROC @@ -1470,11 +1509,11 @@ LOOK_NEXT_TAPE_MSG: inc hl ; Point to next char cp (hl) ; Is it 0Dh? jr nz, LOOK_NEXT_TAPE_MSG - ; Ok next message found + ; Ok next message found djnz LOOK_NEXT_TAPE_MSG ; Repeat if more msg to skip PRINT_TAPE_MSG: - ; Ok. This will print bytes after (HL) - ; until one of them has bit 7 set + ; Ok. This will print bytes after (HL) + ; until one of them has bit 7 set ld a, (hl) and 7Fh ; Clear bit 7 of A call __PRINTCHAR @@ -1485,7 +1524,8 @@ PRINT_TAPE_MSG: pop bc ret ENDP -#line 332 "/zxbasic/src/arch/zx48k/library-asm/load.asm" +#line 334 "/zxbasic/src/arch/zx48k/library-asm/load.asm" + pop namespace #line 33 "load03.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -1559,124 +1599,128 @@ PRINT_TAPE_MSG: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 34 "load03.bas" END diff --git a/tests/functional/loadstr.asm b/tests/functional/loadstr.asm index ac569354b..9dc08e180 100644 --- a/tests/functional/loadstr.asm +++ b/tests/functional/loadstr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,43 +8,43 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _b - call __STORE_STR + call core.__STORE_STR ld hl, (_b) xor a - call VAL - call __STR_FAST + call core.VAL + call core.__STR_FAST ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -133,6 +133,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -162,6 +163,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -287,9 +289,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -297,37 +300,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -340,90 +344,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -493,94 +499,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -602,132 +610,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -752,6 +765,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 31 "loadstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -760,30 +774,32 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 32 "loadstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation @@ -794,12 +810,13 @@ __STORE_STR2: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -814,22 +831,24 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -837,71 +856,75 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" + push namespace core __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - push bc - push de - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - pop de - pop bc - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - ex de, hl ; HL = start of original string - ldir ; Copies string content - pop de ; Original (ROM-CALC) string - pop bc ; Original Length + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + push bc + push de + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + pop de + pop bc + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + ex de, hl ; HL = start of original string + ldir ; Copies string content + pop de ; Original (ROM-CALC) string + pop bc ; Original Length __STR_END: - ex de, hl - inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result - ret + ex de, hl + inc bc + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + pop namespace #line 33 "loadstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/val.asm" + push namespace core VAL: ; Computes VAL(a$) using ROM FP-CALC - ; HL = address of a$ - ; Returns FP number in C ED LH registers - ; A Register = 1 => Free a$ on return - PROC - LOCAL STK_STO_S - LOCAL __RET_ZERO - LOCAL ERR_SP - LOCAL STKBOT - LOCAL RECLAIM1 + ; HL = address of a$ + ; Returns FP number in C ED LH registers + ; A Register = 1 => Free a$ on return + PROC + LOCAL STK_STO_S + LOCAL __RET_ZERO + LOCAL ERR_SP + LOCAL STKBOT + LOCAL RECLAIM1 LOCAL CH_ADD - LOCAL __VAL_ERROR - LOCAL __VAL_EMPTY + LOCAL __VAL_ERROR + LOCAL __VAL_EMPTY LOCAL SET_MIN RECLAIM1 EQU 6629 STKBOT EQU 23651 @@ -910,72 +933,73 @@ VAL: ; Computes VAL(a$) using ROM FP-CALC STK_STO_S EQU 2AB2h SET_MIN EQU 16B0h ld d, a ; Preserves A register in DE - ld a, h - or l - jr z, __RET_ZERO ; NULL STRING => Return 0 + ld a, h + or l + jr z, __RET_ZERO ; NULL STRING => Return 0 push de ; Saves A Register (now in D) - push hl ; Not null string. Save its address for later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string - ex de, hl ; DE = String start + push hl ; Not null string. Save its address for later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string + ex de, hl ; DE = String start ld hl, (CH_ADD) push hl - ld hl, (STKBOT) - push hl - ld hl, (ERR_SP) - push hl + ld hl, (STKBOT) + push hl + ld hl, (ERR_SP) + push hl ;; Now put our error handler on ERR_SP - ld hl, __VAL_ERROR - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - call STK_STO_S ; Enter it on the stack - ld b, 1Dh ; "VAL" - rst 28h ; ROM CALC - defb 1Dh ; VAL - defb 38h ; END CALC - pop hl ; Discards our current error handler - pop hl - ld (ERR_SP), hl ; Restores ERR_SP - pop de ; old STKBOT - ld hl, (STKBOT) ; current SKTBOT - call RECLAIM1 ; Recover unused space + ld hl, __VAL_ERROR + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl + call STK_STO_S ; Enter it on the stack + ld b, 1Dh ; "VAL" + rst 28h ; ROM CALC + defb 1Dh ; VAL + defb 38h ; END CALC + pop hl ; Discards our current error handler + pop hl + ld (ERR_SP), hl ; Restores ERR_SP + pop de ; old STKBOT + ld hl, (STKBOT) ; current SKTBOT + call RECLAIM1 ; Recover unused space pop hl ; Discards old CH_ADD value - pop hl ; String pointer - pop af ; Deletion flag - or a - call nz, __MEM_FREE ; Frees string content before returning + pop hl ; String pointer + pop af ; Deletion flag + or a + call nz, __MEM_FREE ; Frees string content before returning ld a, ERROR_Ok ; Sets OK in the result ld (ERR_NR), a - jp __FPSTACK_POP ; Recovers result and return from there + jp __FPSTACK_POP ; Recovers result and return from there __VAL_ERROR: ; Jumps here on ERROR - pop hl - ld (ERR_SP), hl ; Restores ERR_SP - ld hl, (STKBOT) ; current SKTBOT - pop de ; old STKBOT + pop hl + ld (ERR_SP), hl ; Restores ERR_SP + ld hl, (STKBOT) ; current SKTBOT + pop de ; old STKBOT pop hl ld (CH_ADD), hl ; Recovers old CH_ADD call 16B0h ; Resets temporary areas after an error __VAL_EMPTY: ; Jumps here on empty string - pop hl ; Recovers initial string address - pop af ; String flag: If not 0 => it's temporary - or a - call nz, __MEM_FREE ; Frees "" string + pop hl ; Recovers initial string address + pop af ; String flag: If not 0 => it's temporary + or a + call nz, __MEM_FREE ; Frees "" string __RET_ZERO: ; Returns 0 Floating point on error - ld a, ERROR_InvalidArg - ld (ERR_NR), a - xor a - ld b, a - ld c, a - ld d, b - ld e, c - ret - ENDP + ld a, ERROR_InvalidArg + ld (ERR_NR), a + xor a + ld b, a + ld c, a + ld d, b + ld e, c + ret + ENDP + pop namespace #line 34 "loadstr.bas" END diff --git a/tests/functional/loadu16ii.asm b/tests/functional/loadu16ii.asm index 84e2d43a5..50e758814 100644 --- a/tests/functional/loadu16ii.asm +++ b/tests/functional/loadu16ii.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (__LABEL__test) - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL ld a, (__LABEL__test) ld l, a ld h, 0 @@ -32,18 +32,18 @@ __MAIN_PROGRAM__: ld l, a ld h, 0 ld de, 256 - call __MUL16_FAST + call core.__MUL16_FAST ex de, hl pop hl add hl, de - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,33 +59,35 @@ __LABEL__test: ld hl, 0 ld b, h ld c, l - jp __END_PROGRAM + jp core.__END_PROGRAM ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP -#line 42 "loadu16ii.bas" + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace +#line 15 "loadu16ii.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: ; vim:ts=4:sw=4:et: @@ -93,70 +95,75 @@ __MUL16NOADD: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -186,49 +193,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -236,319 +249,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -603,469 +636,477 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP -#line 43 "loadu16ii.bas" + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace +#line 16 "loadu16ii.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1088,76 +1129,79 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" -#line 44 "loadu16ii.bas" +#line 17 "loadu16ii.bas" END diff --git a/tests/functional/local_array_with_bounds0.asm b/tests/functional/local_array_with_bounds0.asm index ccedd302c..ea07e86e5 100644 --- a/tests/functional/local_array_with_bounds0.asm +++ b/tests/functional/local_array_with_bounds0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -62,7 +62,7 @@ _test: ld hl, -9 ld de, __LABEL0 ld bc, 3 - call __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS ld (ix-1), 1 ld a, (ix-1) ld l, a @@ -72,7 +72,7 @@ _test: pop hl ld de, -9 add hl, de - call __UBOUND + call core.__UBOUND ld a, l ld (0), a ld a, (ix-1) @@ -83,7 +83,7 @@ _test: pop hl ld de, -9 add hl, de - call __LBOUND + call core.__LBOUND ld a, l ld (1), a _test__leave: @@ -91,7 +91,7 @@ _test__leave: exx ld l, (ix-7) ld h, (ix-6) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -177,6 +177,7 @@ _test.a.__UBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -206,6 +207,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -271,9 +273,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -281,37 +284,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -324,90 +328,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -421,25 +427,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -454,6 +462,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -560,7 +569,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 79 "local_array_with_bounds0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -574,6 +584,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -634,6 +645,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 80 "local_array_with_bounds0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -703,94 +715,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 81 "local_array_with_bounds0.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/local_array_with_bounds1.asm b/tests/functional/local_array_with_bounds1.asm index 43951273f..941702423 100644 --- a/tests/functional/local_array_with_bounds1.asm +++ b/tests/functional/local_array_with_bounds1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,7 +60,7 @@ _test: ld hl, -9 ld de, __LABEL0 ld bc, 3 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS ld (ix-1), 1 ld a, (ix-1) ld l, a @@ -70,7 +70,7 @@ _test: pop hl ld de, -9 add hl, de - call __UBOUND + call core.__UBOUND ld a, l ld (0), a ld a, (ix-1) @@ -81,7 +81,7 @@ _test: pop hl ld de, -9 add hl, de - call __LBOUND + call core.__LBOUND ld a, l ld (1), a _test__leave: @@ -89,7 +89,7 @@ _test__leave: exx ld l, (ix-7) ld h, (ix-6) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -175,6 +175,7 @@ _test.a.__UBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -204,6 +205,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -269,9 +271,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -279,37 +282,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -322,90 +326,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -419,25 +425,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -452,6 +460,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -558,7 +567,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 77 "local_array_with_bounds1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -572,6 +582,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -632,6 +643,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 78 "local_array_with_bounds1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -701,94 +713,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 79 "local_array_with_bounds1.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/local_str_array0.asm b/tests/functional/local_str_array0.asm index 986c345af..2087fa0a5 100644 --- a/tests/functional/local_str_array0.asm +++ b/tests/functional/local_str_array0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test - call __MEM_FREE + call core.__MEM_FREE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _test: ld hl, -4 ld de, __LABEL1 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) inc hl @@ -59,7 +59,7 @@ _test: push hl ld de, __LABEL0 pop hl - call __STORE_STR + call core.__STORE_STR ld l, (ix-2) ld h, (ix-1) inc hl @@ -68,7 +68,7 @@ _test: inc hl ld h, (hl) ld l, c - call __LOADSTR + call core.__LOADSTR _test__leave: ex af, af' exx @@ -76,7 +76,7 @@ _test__leave: push hl ld l, (ix-2) ld h, (ix-1) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -171,6 +171,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -200,6 +201,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -265,9 +267,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -275,37 +278,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -318,90 +322,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -415,25 +421,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -448,6 +456,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -497,7 +506,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 73 "local_str_array0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -571,170 +581,176 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 74 "local_str_array0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 76 "local_str_array0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -828,132 +844,137 @@ __LOADSTR: ; __FASTCALL__ entry ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -978,6 +999,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 77 "local_str_array0.bas" __LABEL1: DEFB 00h diff --git a/tests/functional/local_str_array1.asm b/tests/functional/local_str_array1.asm index 180dafd7e..7eb78d4e7 100644 --- a/tests/functional/local_str_array1.asm +++ b/tests/functional/local_str_array1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test - call __MEM_FREE + call core.__MEM_FREE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,24 +54,24 @@ _test: ld hl, -4 ld de, __LABEL1 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld hl, (_i) push hl push ix pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR ld hl, (_i) push hl push ix pop hl ld de, -4 add hl, de - call __ARRAY - call __ILOADSTR + call core.__ARRAY + call core.__ILOADSTR _test__leave: ex af, af' exx @@ -79,7 +79,7 @@ _test__leave: push hl ld l, (ix-2) ld h, (ix-1) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -116,81 +116,84 @@ __LABEL0: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -198,16 +201,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -226,7 +229,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 73 "local_str_array1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -303,6 +307,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -332,6 +337,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -397,9 +403,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -407,37 +414,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -450,90 +458,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -547,25 +557,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -580,6 +592,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -629,7 +642,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 74 "local_str_array1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -703,170 +717,176 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 75 "local_str_array1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 77 "local_str_array1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -960,132 +980,137 @@ __LOADSTR: ; __FASTCALL__ entry ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1110,6 +1135,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 78 "local_str_array1.bas" __LABEL1: DEFB 00h diff --git a/tests/functional/local_str_array2.asm b/tests/functional/local_str_array2.asm index f00eaec8e..10d01f4af 100644 --- a/tests/functional/local_str_array2.asm +++ b/tests/functional/local_str_array2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test - call __MEM_FREE + call core.__MEM_FREE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,7 +60,7 @@ _test: ld hl, -6 ld de, __LABEL2 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) push hl @@ -68,9 +68,9 @@ _test: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR ld l, (ix-2) ld h, (ix-1) push hl @@ -78,8 +78,8 @@ _test: pop hl ld de, -6 add hl, de - call __ARRAY - call __ILOADSTR + call core.__ARRAY + call core.__ILOADSTR _test__leave: ex af, af' exx @@ -87,7 +87,7 @@ _test__leave: push hl ld l, (ix-4) ld h, (ix-3) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -124,81 +124,84 @@ __LABEL0: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -206,16 +209,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -234,7 +237,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 84 "local_str_array2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -311,6 +315,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -340,6 +345,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -405,9 +411,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -415,37 +422,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -458,90 +466,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -555,25 +565,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -588,6 +600,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -637,7 +650,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 85 "local_str_array2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -711,170 +725,176 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 86 "local_str_array2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 88 "local_str_array2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -968,132 +988,137 @@ __LOADSTR: ; __FASTCALL__ entry ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1118,6 +1143,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 89 "local_str_array2.bas" __LABEL1: DEFB 01h diff --git a/tests/functional/local_str_array3.asm b/tests/functional/local_str_array3.asm index 79dfb9d0a..49fbd6182 100644 --- a/tests/functional/local_str_array3.asm +++ b/tests/functional/local_str_array3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 push hl call _test - call __MEM_FREE + call core.__MEM_FREE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,7 +54,7 @@ _test: ld hl, -6 ld de, __LABEL6 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld (ix-2), 0 ld (ix-1), 0 jp __LABEL0 @@ -66,9 +66,9 @@ __LABEL3: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY ld de, __LABEL5 - call __STORE_STR + call core.__STORE_STR __LABEL4: ld l, (ix-2) ld h, (ix-1) @@ -92,8 +92,8 @@ __LABEL2: pop hl ld de, -6 add hl, de - call __ARRAY - call __ILOADSTR + call core.__ARRAY + call core.__ILOADSTR _test__leave: ex af, af' exx @@ -101,7 +101,7 @@ _test__leave: push hl ld l, (ix-4) ld h, (ix-3) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -143,81 +143,84 @@ __LABEL5: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -225,16 +228,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -253,7 +256,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 103 "local_str_array3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -330,6 +334,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -359,6 +364,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -424,9 +430,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -434,37 +441,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -477,90 +485,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -574,25 +584,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -607,6 +619,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -656,7 +669,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 104 "local_str_array3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -730,170 +744,176 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 105 "local_str_array3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 107 "local_str_array3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -987,132 +1007,137 @@ __LOADSTR: ; __FASTCALL__ entry ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1137,6 +1162,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 108 "local_str_array3.bas" __LABEL6: DEFB 00h diff --git a/tests/functional/local_u16_array0.asm b/tests/functional/local_u16_array0.asm index 03850f76d..86b402ea3 100644 --- a/tests/functional/local_u16_array0.asm +++ b/tests/functional/local_u16_array0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 8 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) ld de, 6 @@ -77,7 +77,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -159,6 +159,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -188,6 +189,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -253,9 +255,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -263,37 +266,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -306,90 +310,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -403,25 +409,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -436,6 +444,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -485,7 +494,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 61 "local_u16_array0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -555,94 +565,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 62 "local_u16_array0.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/local_u16_array1.asm b/tests/functional/local_u16_array1.asm index d785d73e5..1afebaf74 100644 --- a/tests/functional/local_u16_array1.asm +++ b/tests/functional/local_u16_array1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 01h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,14 +53,14 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld hl, (_i) push hl push ix pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY ld de, 3 ld (hl), e inc hl @@ -71,7 +71,7 @@ _test: pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) @@ -81,7 +81,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -105,81 +105,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -187,16 +190,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -215,7 +218,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 62 "local_u16_array1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -292,6 +296,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -321,6 +326,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -386,9 +392,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -396,37 +403,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -439,90 +447,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -536,25 +546,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -569,6 +581,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -618,7 +631,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 63 "local_u16_array1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -688,94 +702,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 64 "local_u16_array1.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/local_u16_array2.asm b/tests/functional/local_u16_array2.asm index 637b0848c..f47f79046 100644 --- a/tests/functional/local_u16_array2.asm +++ b/tests/functional/local_u16_array2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,7 +59,7 @@ _test: ld hl, -6 ld de, __LABEL1 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) push hl @@ -67,7 +67,7 @@ _test: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY ld de, 3 ld (hl), e inc hl @@ -79,7 +79,7 @@ _test: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) @@ -89,7 +89,7 @@ _test__leave: exx ld l, (ix-4) ld h, (ix-3) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -113,81 +113,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -195,16 +198,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -223,7 +226,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 73 "local_u16_array2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -300,6 +304,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -329,6 +334,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -394,9 +400,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -404,37 +411,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -447,90 +455,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -544,25 +554,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -577,6 +589,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -626,7 +639,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 74 "local_u16_array2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -696,94 +710,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 75 "local_u16_array2.bas" __LABEL0: DEFB 01h diff --git a/tests/functional/local_u16_array3.asm b/tests/functional/local_u16_array3.asm index 4fe8c4d4e..193a69717 100644 --- a/tests/functional/local_u16_array3.asm +++ b/tests/functional/local_u16_array3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,7 +53,7 @@ _test: ld hl, -6 ld de, __LABEL5 ld bc, 8 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld (ix-2), 0 ld (ix-1), 0 jp __LABEL0 @@ -69,7 +69,7 @@ __LABEL3: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY pop de ld (hl), e inc hl @@ -97,7 +97,7 @@ __LABEL2: pop hl ld de, -6 add hl, de - call __ARRAY + call core.__ARRAY ld e, (hl) inc hl ld d, (hl) @@ -107,7 +107,7 @@ _test__leave: exx ld l, (ix-4) ld h, (ix-3) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -135,81 +135,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -217,16 +220,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -245,7 +248,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 95 "local_u16_array3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -322,6 +326,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -351,6 +356,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -416,9 +422,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -426,37 +433,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -469,90 +477,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -566,25 +576,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -599,6 +611,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -648,7 +661,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 96 "local_u16_array3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -718,94 +732,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 97 "local_u16_array3.bas" __LABEL5: DEFB 00h diff --git a/tests/functional/localbyref.asm b/tests/functional/localbyref.asm index fceeb098d..369136804 100644 --- a/tests/functional/localbyref.asm +++ b/tests/functional/localbyref.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _primero ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ltee1.asm b/tests/functional/ltee1.asm index 9506b639f..8cd9a8a32 100644 --- a/tests/functional/ltee1.asm +++ b/tests/functional/ltee1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,43 +8,43 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _newMsg: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _addWibble ex de, hl ld hl, _newMsg - call __STORE_STR2 + call core.__STORE_STR2 ld hl, (_newMsg) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,29 +64,29 @@ _addWibble: ld d, h ld e, l ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-2) ld h, (ix-1) push hl ld de, __LABEL1 pop hl - call __ADDSTR + call core.__ADDSTR ld d, h ld e, l ld bc, -2 - call __PSTORE_STR2 + call core.__PSTORE_STR2 ld l, (ix-2) ld h, (ix-1) - call __LOADSTR + call core.__LOADSTR _addWibble__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -236,9 +236,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -246,37 +247,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -286,94 +288,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 86 "ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -439,6 +443,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -468,6 +473,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -480,125 +486,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 87 "ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -610,109 +620,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -720,319 +739,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1087,468 +1126,475 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 88 "ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 89 "ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -1648,132 +1694,137 @@ __PRINT_STR: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1798,12 +1849,15 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 90 "ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" ; vim:ts=4:et:sw=4 @@ -1819,144 +1873,152 @@ __PSTORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" + push namespace core __PSTORE_STR2: push ix pop hl add hl, bc jp __STORE_STR2 + pop namespace #line 91 "ltee1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 93 "ltee1.bas" END diff --git a/tests/functional/ltee10.asm b/tests/functional/ltee10.asm index b42cb15a7..0fd610ae5 100644 --- a/tests/functional/ltee10.asm +++ b/tests/functional/ltee10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _pos: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,7 +53,7 @@ _setlocal: ld hl, -4 ld de, __LABEL0 ld bc, 3 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld a, (_pos) ld l, a ld h, 0 @@ -62,14 +62,14 @@ _setlocal: pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY ld (hl), 3 _setlocal__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -93,81 +93,84 @@ _setlocal__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -175,16 +178,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -203,7 +206,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 51 "ltee10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -280,6 +284,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -309,6 +314,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -374,9 +380,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -384,37 +391,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -427,90 +435,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -524,25 +534,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -557,6 +569,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -606,7 +619,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 52 "ltee10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -676,94 +690,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 53 "ltee10.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/ltee3.asm b/tests/functional/ltee3.asm index db03bd67d..b12bfdda6 100644 --- a/tests/functional/ltee3.asm +++ b/tests/functional/ltee3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -197,9 +197,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -207,37 +208,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -247,94 +249,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 50 "ltee3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -400,6 +404,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -429,6 +434,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -441,124 +447,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 51 "ltee3.bas" END diff --git a/tests/functional/ltee4.asm b/tests/functional/ltee4.asm index 6df2ae16f..be8d0df89 100644 --- a/tests/functional/ltee4.asm +++ b/tests/functional/ltee4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _hsName: DEFW __LABEL0 _hsName.__DATA__.__PTR__: @@ -37,16 +37,16 @@ _hsName.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_hsName.__DATA__ + 1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ltee5.asm b/tests/functional/ltee5.asm index a38813a32..62d0abac9 100644 --- a/tests/functional/ltee5.asm +++ b/tests/functional/ltee5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _testglobal: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _testglobal - call __STORE_STR + call core.__STORE_STR call _setlocal ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,18 +53,18 @@ _setlocal: push hl ld de, __LABEL1 ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-2) ld h, (ix-1) ex de, hl ld hl, _testglobal - call __STORE_STR + call core.__STORE_STR _setlocal__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,94 +262,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 61 "ltee5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -430,6 +434,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -459,6 +464,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -531,90 +537,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -636,132 +644,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -786,11 +799,14 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 62 "ltee5.bas" END diff --git a/tests/functional/ltee6.asm b/tests/functional/ltee6.asm index b8fc6052e..29ae70fed 100644 --- a/tests/functional/ltee6.asm +++ b/tests/functional/ltee6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _pos: DEFB 00 _testglobal: @@ -45,22 +45,22 @@ _testglobal.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_pos) ld l, a ld h, 0 push hl ld hl, _testglobal - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -95,81 +95,84 @@ __LABEL0: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -177,16 +180,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -205,7 +208,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 33 "ltee6.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -282,6 +286,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -311,6 +316,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -436,9 +442,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -446,37 +453,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -489,90 +497,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -642,94 +652,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -751,132 +763,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -901,5 +918,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 34 "ltee6.bas" END diff --git a/tests/functional/ltee7.asm b/tests/functional/ltee7.asm index 4063ee4d3..516b97205 100644 --- a/tests/functional/ltee7.asm +++ b/tests/functional/ltee7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _pos: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _setlocal: ld hl, -4 ld de, __LABEL1 ld bc, 12 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld a, (_pos) ld l, a ld h, 0 @@ -60,9 +60,9 @@ _setlocal: pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY ld de, __LABEL0 - call __STORE_STR + call core.__STORE_STR _setlocal__leave: ex af, af' exx @@ -70,7 +70,7 @@ _setlocal__leave: push hl ld l, (ix-2) ld h, (ix-1) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -101,81 +101,84 @@ __LABEL0: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -183,16 +186,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -211,7 +214,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 59 "ltee7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -288,6 +292,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -317,6 +322,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -382,9 +388,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -392,37 +399,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -435,90 +443,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -532,25 +542,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -565,6 +577,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -614,7 +627,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 60 "ltee7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -688,134 +702,138 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 61 "ltee7.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -909,132 +927,137 @@ __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1059,6 +1082,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 62 "ltee7.bas" __LABEL1: DEFB 00h diff --git a/tests/functional/ltee8.asm b/tests/functional/ltee8.asm index 1af80391e..cf204ecfc 100644 --- a/tests/functional/ltee8.asm +++ b/tests/functional/ltee8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (((_a) / (256)) & 0xFFFFFFFF) & 0xFF ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ltee9.asm b/tests/functional/ltee9.asm index 2a47f4d54..5be68790c 100644 --- a/tests/functional/ltee9.asm +++ b/tests/functional/ltee9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__UDGS: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,18 +57,18 @@ __LABEL__UDGS: push hl ld hl, ((((__LABEL__UDGS) / (256)) & 0xFFFFFFFF) * (256)) & 0xFFFF ld de, ((((__LABEL__UDGS) / (256)) & 0xFFFFFFFF) * (256)) >> 16 - call __SUB32 + call core.__SUB32 ld (_x), hl ld hl, (((__LABEL__UDGS) & 0xFFFFFFFF) - ((((__LABEL__UDGS) / (256)) & 0xFFFFFFFF) * (256))) & 0xFFFF ld de, (((__LABEL__UDGS) & 0xFFFFFFFF) - ((((__LABEL__UDGS) / (256)) & 0xFFFFFFFF) * (256))) >> 16 ld bc, -4 - call __PSTORE32 + call core.__PSTORE32 ld hl, (_x) ld de, 256 - call __DIVU16 + call core.__DIVU16 ld (_x), hl ld de, 256 - call __DIVU16 + call core.__DIVU16 ld de, 0 ld (_x), hl ld de, 0 @@ -76,28 +76,28 @@ __LABEL__UDGS: push hl ld hl, (_x) ld de, 256 - call __DIVU16 + call core.__DIVU16 ld de, 0 push de push hl ld de, 0 ld hl, 256 - call __MUL32 - call __SUB32 + call core.__MUL32 + call core.__SUB32 ld (_x), hl ld de, 0 push de push hl ld hl, (_x) ld de, 256 - call __DIVU16 + call core.__DIVU16 ld de, 0 push de push hl ld de, 0 ld hl, 256 - call __MUL32 - call __SUB32 + call core.__MUL32 + call core.__SUB32 ld (_x), hl _start__leave: ld sp, ix @@ -109,23 +109,26 @@ _start__leave: ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -148,50 +151,51 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 84 "ltee9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" @@ -199,131 +203,142 @@ __MODI16: ; 16 bit modulus ; Used with permission. ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') ; 64bit result is returned in H'L'H L B'C'A C + push namespace core __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP - ret ; result in h'l'hlb'c'ac + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" -__MUL32: ; multiplies 32 bit un/signed integer. - ; First operand stored in DEHL, and 2nd onto stack - ; Lowest part of 2nd operand on top of the stack - ; returns the result in DE.HL - exx - pop hl ; Return ADDRESS - pop de ; Low part - ex (sp), hl ; CALLEE -> HL = High part - ex de, hl - call __MUL32_64START + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) - exx - push bc - exx - pop de - ld h, a - ld l, c - ret + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace #line 85 "ltee9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstore32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" + push namespace core __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/pstore32.asm" ; Stores a 32 bit integer number (DE,HL) at (IX + BC) + push namespace core __PSTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc - jp __STORE32 + push hl + push ix + pop hl + add hl, bc + pop bc + jp __STORE32 + pop namespace #line 86 "ltee9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sub32.asm" ; SUB32 ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 87 "ltee9.bas" END diff --git a/tests/functional/ltf16.asm b/tests/functional/ltf16.asm index a7b162fd4..8679c9026 100644 --- a/tests/functional/ltf16.asm +++ b/tests/functional/ltf16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LTI32 + call core.__SWAP32 + call core.__LTI32 ld l, a ld h, 0 ex de, hl @@ -52,7 +52,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ex de, hl @@ -65,7 +65,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ex de, hl @@ -78,7 +78,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ex de, hl @@ -88,9 +88,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -106,26 +106,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lti32.asm" + push namespace core __LTI32: ; Test 32 bit values in Top of the stack < HLDE PROC LOCAL checkParity @@ -145,12 +148,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 70 "ltf16.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -160,6 +165,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 71 "ltf16.bas" END diff --git a/tests/functional/lti32c.asm b/tests/functional/lti32c.asm index a5f95d03a..9c2a624e6 100644 --- a/tests/functional/lti32c.asm +++ b/tests/functional/lti32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __LTI32 + call core.__SWAP32 + call core.__LTI32 ld l, a ld h, 0 ld e, h @@ -52,7 +52,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ld e, h @@ -65,7 +65,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ld e, h @@ -78,7 +78,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ld e, h @@ -91,7 +91,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __LTI32 + call core.__LTI32 ld l, a ld h, 0 ld e, h @@ -101,9 +101,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -119,26 +119,29 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lti32.asm" + push namespace core __LTI32: ; Test 32 bit values in Top of the stack < HLDE PROC LOCAL checkParity @@ -158,12 +161,14 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 83 "lti32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -173,6 +178,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 84 "lti32c.bas" END diff --git a/tests/functional/ltu32c.asm b/tests/functional/ltu32c.asm index 780cb65ce..c62a07abf 100644 --- a/tests/functional/ltu32c.asm +++ b/tests/functional/ltu32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __SUB32 + call core.__SWAP32 + call core.__SUB32 sbc a, a ld l, a ld h, 0 @@ -53,7 +53,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 sbc a, a ld l, a ld h, 0 @@ -67,7 +67,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 sbc a, a ld l, a ld h, 0 @@ -81,7 +81,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 sbc a, a ld l, a ld h, 0 @@ -95,7 +95,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __SUB32 + call core.__SUB32 sbc a, a ld l, a ld h, 0 @@ -106,9 +106,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -123,31 +123,34 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 88 "ltu32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -157,6 +160,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 89 "ltu32c.bas" END diff --git a/tests/functional/lvalsubstr_nolet.asm b/tests/functional/lvalsubstr_nolet.asm index 80714de5f..11c4eba4a 100644 --- a/tests/functional/lvalsubstr_nolet.asm +++ b/tests/functional/lvalsubstr_nolet.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl xor a @@ -36,13 +36,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -188,9 +188,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -198,37 +199,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -238,203 +240,207 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 30 "lvalsubstr_nolet.bas" END diff --git a/tests/functional/mcleod.asm b/tests/functional/mcleod.asm index 8de9f4005..45fd797a3 100644 --- a/tests/functional/mcleod.asm +++ b/tests/functional/mcleod.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call RND +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.RND push bc push de push af ld a, 083h ld de, 00000h ld bc, 00000h - call __MULF - call __FTOU32REG + call core.__MULF + call core.__FTOU32REG ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,77 +50,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -137,23 +140,25 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 28 "mcleod.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -168,19 +173,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -190,16 +196,19 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 29 "mcleod.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/random.asm" ; RANDOM functions + push namespace core RANDOMIZE: ; Randomize with 32 bit seed in DE HL ; if SEED = 0, calls ROM to take frames as seed @@ -296,5 +305,6 @@ RND_LOOP: ld a, l ; exponent in A ret ENDP + pop namespace #line 30 "mcleod.bas" END diff --git a/tests/functional/mcleod2.asm b/tests/functional/mcleod2.asm index b30324574..5d9517129 100644 --- a/tests/functional/mcleod2.asm +++ b/tests/functional/mcleod2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -122,6 +122,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -151,6 +152,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -276,9 +278,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -286,37 +289,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -329,90 +333,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -482,94 +488,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -591,132 +599,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -741,5 +754,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 22 "mcleod2.bas" END diff --git a/tests/functional/memcpytest.asm b/tests/functional/memcpytest.asm index b8a9c39cb..f71b3e694 100644 --- a/tests/functional/memcpytest.asm +++ b/tests/functional/memcpytest.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call CLS +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.CLS ld a, 1 ld (_i), a jp __LABEL0 __LABEL3: ld hl, __LABEL5 xor a - call __PRINTSTR + call core.__PRINTSTR __LABEL4: ld hl, _i inc (hl) @@ -51,9 +51,9 @@ __LABEL2: push hl ld hl, 16384 call _MemCopy - call CLS + call core.CLS ld hl, 0 - call __PAUSE + call core.__PAUSE ld hl, 6912 push hl ld hl, 16384 @@ -63,9 +63,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -135,61 +135,65 @@ __LABEL5: ; Our faster implementation #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP -#line 102 "memcpytest.bas" + ; to get the start of the screen + ENDP + pop namespace +#line 128 "/zxbasic/src/arch/zx48k/library/memcopy.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/memcopy.asm" ; ---------------------------------------------------------------- ; This file is released under the MIT License @@ -204,19 +208,20 @@ __CLS_SCR: ; HL => Start of source block ; DE => Start of destiny block ; BC => Block length + push namespace core __MEMCPY: PROC LOCAL __MEMCPY2 push hl - add hl, bc ; addr of last source block byte + 1 + add hl, bc ; addr of last source block byte + 1 or a sbc hl, de ; checks if DE > HL + BC pop hl ; recovers HL. If carry => DE > HL + BC (no overlap) jr c, __MEMCPY2 - ; Now checks if DE <= HL - sbc hl, de ; Even if overlap, if DE < HL then we can LDIR safely - add hl, de - jr nc, __MEMCPY2 + ; Now checks if DE <= HL + sbc hl, de ; Even if overlap, if DE < HL then we can LDIR safely + add hl, de + jr nc, __MEMCPY2 dec bc add hl, bc ex de, hl @@ -228,15 +233,18 @@ __MEMCPY: __MEMCPY2: ldir ret - ENDP -#line 103 "memcpytest.bas" + ENDP + pop namespace +#line 129 "/zxbasic/src/arch/zx48k/library/memcopy.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pause.asm" ; The PAUSE statement (Calling the ROM) + push namespace core __PAUSE: - ld b, h + ld b, h ld c, l jp 1F3Dh ; PAUSE_1 -#line 104 "memcpytest.bas" + pop namespace +#line 130 "/zxbasic/src/arch/zx48k/library/memcopy.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -247,6 +255,7 @@ __PAUSE: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -276,49 +285,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -326,319 +341,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -693,422 +728,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1234,9 +1272,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1244,37 +1283,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1284,134 +1324,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP -#line 105 "memcpytest.bas" + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace +#line 131 "/zxbasic/src/arch/zx48k/library/memcopy.bas" END diff --git a/tests/functional/modf16.asm b/tests/functional/modf16.asm index 6970b73e2..b10ffaa01 100644 --- a/tests/functional/modf16.asm +++ b/tests/functional/modf16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) ld hl, 0 @@ -32,9 +32,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/modf16c.asm b/tests/functional/modf16c.asm index 582a6850d..3551f6f11 100644 --- a/tests/functional/modf16c.asm +++ b/tests/functional/modf16c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __MODF16 + call core.__SWAP32 + call core.__MODF16 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __MODF16 + call core.__MODF16 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __MODF16 + call core.__MODF16 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -66,7 +66,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __MODF16 + call core.__MODF16 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -75,15 +75,15 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __MODF16 + call core.__MODF16 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -98,207 +98,213 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/divf16.asm" + push namespace core __DIVF16: ; 16.16 Fixed point Division (signed) - ; DE.HL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - ex de, hl ; D'E'.H'L' Dividend + ; DE.HL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ex de, hl ; D'E'.H'L' Dividend __DIVF16START: ; FAST Entry: DEHL => Dividend, D'E'H'L' => Divisor - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with D'E'.H'L' - ex af, af' - xor d - ex af, af' ; Stores sign of the result for later - bit 7, d ; Negative? - call nz, __NEG32 - exx ; Now we have DE.HL => Dividend - ld b, 16 + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with D'E'.H'L' + ex af, af' + xor d + ex af, af' ; Stores sign of the result for later + bit 7, d ; Negative? + call nz, __NEG32 + exx ; Now we have DE.HL => Dividend + ld b, 16 __SHIFTALOOP: ; Tries to shift Dividend to the left - bit 7, d - jp nz, __SHIFTB - add hl, hl - ex de, hl - adc hl, hl - ex de, hl - djnz __SHIFTALOOP - jp __DOF16_DIVRDY + bit 7, d + jp nz, __SHIFTB + add hl, hl + ex de, hl + adc hl, hl + ex de, hl + djnz __SHIFTALOOP + jp __DOF16_DIVRDY __SHIFTB: ; Cannot shift Dividend more to the left, try to shift Divisor to the right - ld a, b - exx - ld b, a - ; Divisor is in DEHL + ld a, b + exx + ld b, a + ; Divisor is in DEHL __SHIFTBLOOP: - bit 1, l - jp nz, __DOF16_DIVIDE - sra d - rr e - rr h - rr l - djnz __SHIFTBLOOP + bit 1, l + jp nz, __DOF16_DIVIDE + sra d + rr e + rr h + rr l + djnz __SHIFTBLOOP __DOF16_DIVIDE: - ld a, b - exx - ld b, a + ld a, b + exx + ld b, a __DOF16_DIVRDY: - exx - ex de, hl - push bc - call __DIVU32START - pop bc - xor a - or b - jp z, __ENDF16DIV + exx + ex de, hl + push bc + call __DIVU32START + pop bc + xor a + or b + jp z, __ENDF16DIV __SHIFTCLOOP: - add hl, hl ; Shift DECIMAL PART << 1 - ex de, hl - adc hl, hl ; Shift INTEGER PART << 1 Plus Carry - ex de, hl - djnz __SHIFTCLOOP + add hl, hl ; Shift DECIMAL PART << 1 + ex de, hl + adc hl, hl ; Shift INTEGER PART << 1 Plus Carry + ex de, hl + djnz __SHIFTCLOOP __ENDF16DIV: ; Put the sign on the result - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/modf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" @@ -306,120 +312,127 @@ __ENDF16DIV: ; Put the sign on the result ; Used with permission. ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') ; 64bit result is returned in H'L'H L B'C'A C + push namespace core __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP - ret ; result in h'l'hlb'c'ac + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" + push namespace core __MULF16: ; - ld a, d ; load sgn into a - ex af, af' ; saves it - call __ABS32 ; convert to positive - exx - pop hl ; Return address - pop de ; Low part - ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address - ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) - ex af, af' - xor d ; A register contains resulting sgn - ex af, af' - call __ABS32 ; convert to positive - call __MUL32_64START + ld a, d ; load sgn into a + ex af, af' ; saves it + call __ABS32 ; convert to positive + exx + pop hl ; Return address + pop de ; Low part + ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address + ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) + ex af, af' + xor d ; A register contains resulting sgn + ex af, af' + call __ABS32 ; convert to positive + call __MUL32_64START ; rounding (was not included in zx81) __ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 - ; result returned in dehl - ; input in h'l'hlb'c'ac - sla a ; result bit 47 to carry - exx - ld hl,0 ; ld does not change carry - adc hl,bc ; hl = hl + 0 + carry - push hl - exx - ld bc,0 - adc hl,bc ; hl = hl + 0 + carry - ex de, hl - pop hl ; rounded result in de.hl - ex af, af' ; recovers result sign - or a - jp m, __NEG32 ; if negative, negates it - ret + ; result returned in dehl + ; input in h'l'hlb'c'ac + sla a ; result bit 47 to carry + exx + ld hl,0 ; ld does not change carry + adc hl,bc ; hl = hl + 0 + carry + push hl + exx + ld bc,0 + adc hl,bc ; hl = hl + 0 + carry + ex de, hl + pop hl ; rounded result in de.hl + ex af, af' ; recovers result sign + or a + jp m, __NEG32 ; if negative, negates it + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/modf16.asm" + push namespace core __MODF16: - ; 16.16 Fixed point Division (signed) - ; DE.HL = Divisor, Stack Top = Divider - ; A = Dividend, B = Divisor => A % B + ; 16.16 Fixed point Division (signed) + ; DE.HL = Divisor, Stack Top = Divider + ; A = Dividend, B = Divisor => A % B PROC LOCAL TEMP TEMP EQU 23698 ; MEMBOT pop bc ; ret addr ld (TEMP), bc ; stores it on MEMBOT temporarily - ld (TEMP + 2), hl ; stores HP of divider - ld (TEMP + 4), de ; stores DE of divider + ld (TEMP + 2), hl ; stores HP of divider + ld (TEMP + 4), de ; stores DE of divider call __DIVF16 - rlc d ; Sign into carry - sbc a, a ; a register = -1 sgn(DE), or 0 - ld d, a - ld e, a ; DE = 0 if it was positive or 0; -1 if it was negative - ld bc, (TEMP + 4) ; Pushes original divider into the stack - push bc - ld bc, (TEMP + 2) - push bc + rlc d ; Sign into carry + sbc a, a ; a register = -1 sgn(DE), or 0 + ld d, a + ld e, a ; DE = 0 if it was positive or 0; -1 if it was negative + ld bc, (TEMP + 4) ; Pushes original divider into the stack + push bc + ld bc, (TEMP + 2) + push bc ld bc, (TEMP) ; recovers return address push bc jp __MULF16 ; multiplies and return from there ENDP + pop namespace #line 63 "modf16c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -429,6 +442,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 64 "modf16c.bas" END diff --git a/tests/functional/modi32c.asm b/tests/functional/modi32c.asm index 41c3341aa..81ab0c65d 100644 --- a/tests/functional/modi32c.asm +++ b/tests/functional/modi32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,15 +30,15 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __MODI32 + call core.__MODI32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -47,8 +47,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __MODI32 + call core.__SWAP32 + call core.__MODI32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,8 +57,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __MODI32 + call core.__SWAP32 + call core.__MODI32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -67,8 +67,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __MODI32 + call core.__SWAP32 + call core.__MODI32 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -77,16 +77,16 @@ __MAIN_PROGRAM__: push bc ld bc, 2 push bc - call __SWAP32 - call __MODI32 + call core.__SWAP32 + call core.__MODI32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -98,145 +98,150 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 66 "modi32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -246,6 +251,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 67 "modi32c.bas" END diff --git a/tests/functional/modi8.asm b/tests/functional/modi8.asm index 37f03024e..d30b131c5 100644 --- a/tests/functional/modi8.asm +++ b/tests/functional/modi8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_b), a ld a, (_a) @@ -36,26 +36,26 @@ __MAIN_PROGRAM__: ld (_b), a ld a, 1 ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld (_b), a ld a, 2 ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld (_b), a ld a, 4 ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld (_b), a ld a, (_a) ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -66,67 +66,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 43 "modi8.bas" END diff --git a/tests/functional/modi8a.asm b/tests/functional/modi8a.asm index 06f63536b..ec932beae 100644 --- a/tests/functional/modi8a.asm +++ b/tests/functional/modi8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,67 +44,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 23 "modi8a.bas" END diff --git a/tests/functional/modi8b.asm b/tests/functional/modi8b.asm index 93561d963..8fcffb768 100644 --- a/tests/functional/modi8b.asm +++ b/tests/functional/modi8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST push af ld a, (_a) and 1 ld hl, (_a - 1) - call __MODI8_FAST + call core.__MODI8_FAST ld h, a pop af - call __MODI8_FAST + call core.__MODI8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,67 +50,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 29 "modi8b.bas" END diff --git a/tests/functional/modu32c.asm b/tests/functional/modu32c.asm index 3dcb74072..26d94c610 100644 --- a/tests/functional/modu32c.asm +++ b/tests/functional/modu32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,15 +30,15 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __MODU32 + call core.__MODU32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -47,8 +47,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __MODU32 + call core.__SWAP32 + call core.__MODU32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,8 +57,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __MODU32 + call core.__SWAP32 + call core.__MODU32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -67,8 +67,8 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SWAP32 - call __MODU32 + call core.__SWAP32 + call core.__MODU32 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -77,16 +77,16 @@ __MAIN_PROGRAM__: push bc ld bc, 2 push bc - call __SWAP32 - call __MODU32 + call core.__SWAP32 + call core.__MODU32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -98,145 +98,150 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 66 "modu32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -246,6 +251,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 67 "modu32c.bas" END diff --git a/tests/functional/modu8.asm b/tests/functional/modu8.asm index 8596cbab2..5ea779f2e 100644 --- a/tests/functional/modu8.asm +++ b/tests/functional/modu8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_b), a ld a, (_a) @@ -36,26 +36,26 @@ __MAIN_PROGRAM__: ld (_b), a ld a, 1 ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld (_b), a ld a, 2 ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld (_b), a ld a, 4 ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld (_b), a ld a, (_a) ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -66,67 +66,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 43 "modu8.bas" END diff --git a/tests/functional/modu8a.asm b/tests/functional/modu8a.asm index 62b15f22a..a7ecc44fc 100644 --- a/tests/functional/modu8a.asm +++ b/tests/functional/modu8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,67 +44,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 23 "modu8a.bas" END diff --git a/tests/functional/modu8b.asm b/tests/functional/modu8b.asm index 987ce0f4a..b2c4921ef 100644 --- a/tests/functional/modu8b.asm +++ b/tests/functional/modu8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST push af ld a, (_a) and 1 ld hl, (_a - 1) - call __MODU8_FAST + call core.__MODU8_FAST ld h, a pop af - call __MODU8_FAST + call core.__MODU8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,67 +50,69 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 29 "modu8b.bas" END diff --git a/tests/functional/mul16.asm b/tests/functional/mul16.asm index eb7fa1393..a279eb6d6 100644 --- a/tests/functional/mul16.asm +++ b/tests/functional/mul16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld (_b), hl ld hl, (_a) @@ -34,14 +34,14 @@ __MAIN_PROGRAM__: ld (_b), hl ld de, (_a) ld hl, (_a) - call __MUL16_FAST + call core.__MUL16_FAST ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,28 +52,30 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 29 "mul16.bas" END diff --git a/tests/functional/mul16a.asm b/tests/functional/mul16a.asm index d8ee8dcd6..a3e64e976 100644 --- a/tests/functional/mul16a.asm +++ b/tests/functional/mul16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_a) ld hl, (_a) - call __MUL16_FAST + call core.__MUL16_FAST ex de, hl ld hl, (_a) - call __MUL16_FAST + call core.__MUL16_FAST ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,28 +45,30 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 24 "mul16a.bas" END diff --git a/tests/functional/mul16b.asm b/tests/functional/mul16b.asm index ff585339b..c1ee345e9 100644 --- a/tests/functional/mul16b.asm +++ b/tests/functional/mul16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_a) ld hl, (_a) - call __MUL16_FAST + call core.__MUL16_FAST push hl ld hl, (_a) add hl, hl ex de, hl ld hl, (_a) - call __MUL16_FAST + call core.__MUL16_FAST ex de, hl pop hl - call __MUL16_FAST + call core.__MUL16_FAST ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,28 +51,30 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 30 "mul16b.bas" END diff --git a/tests/functional/mul16c.asm b/tests/functional/mul16c.asm index 26d23cc89..764643be8 100644 --- a/tests/functional/mul16c.asm +++ b/tests/functional/mul16c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, -1 - call __MUL16_FAST + call core.__MUL16_FAST ld (_a), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,28 +42,30 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 21 "mul16c.bas" END diff --git a/tests/functional/mul8.asm b/tests/functional/mul8.asm index 851504270..3e571230b 100644 --- a/tests/functional/mul8.asm +++ b/tests/functional/mul8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) xor a ld (_b), a @@ -50,14 +50,14 @@ __MAIN_PROGRAM__: ld (_b), a ld hl, (_a - 1) ld a, (_a) - call __MUL8_FAST + call core.__MUL8_FAST ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -68,14 +68,15 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -109,7 +110,8 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 45 "mul8.bas" END diff --git a/tests/functional/mul8a.asm b/tests/functional/mul8a.asm index 809e5c4dd..dd7bdf870 100644 --- a/tests/functional/mul8a.asm +++ b/tests/functional/mul8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a - 1) ld a, (_a) - call __MUL8_FAST + call core.__MUL8_FAST ld h, a ld a, (_a) - call __MUL8_FAST + call core.__MUL8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,14 +45,15 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -86,7 +87,8 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 24 "mul8a.bas" END diff --git a/tests/functional/mul8b.asm b/tests/functional/mul8b.asm index 7a2f73391..a180c5197 100644 --- a/tests/functional/mul8b.asm +++ b/tests/functional/mul8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a - 1) ld a, (_a) - call __MUL8_FAST + call core.__MUL8_FAST push af ld a, (_a) add a, a ld h, a ld a, (_a) - call __MUL8_FAST + call core.__MUL8_FAST ld h, a pop af - call __MUL8_FAST + call core.__MUL8_FAST ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,14 +51,15 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -92,7 +93,8 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 30 "mul8b.bas" END diff --git a/tests/functional/mulf00.asm b/tests/functional/mulf00.asm index 2fb2e9ec3..703152a68 100644 --- a/tests/functional/mulf00.asm +++ b/tests/functional/mulf00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 80h DEFB 00h @@ -30,22 +30,22 @@ _b: DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _b + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 082h ld de, 00000h ld bc, 00000h - call __MULF + call core.__MULF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,12 +60,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -80,19 +81,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -102,19 +104,22 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 25 "mulf00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -135,32 +140,35 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 26 "mulf00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 27 "mulf00.bas" END diff --git a/tests/functional/mulf01.asm b/tests/functional/mulf01.asm index 124c4bf78..92d417181 100644 --- a/tests/functional/mulf01.asm +++ b/tests/functional/mulf01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 80h DEFB 00h @@ -30,8 +30,8 @@ _b: DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) @@ -41,15 +41,15 @@ __MAIN_PROGRAM__: push hl ld h, 082h push hl - call __MULF + call core.__MULF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,12 +64,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -84,19 +85,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -106,39 +108,43 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 29 "mulf01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 30 "mulf01.bas" END diff --git a/tests/functional/mulf16a.asm b/tests/functional/mulf16a.asm index 1d34ef7dd..d2f5c26b1 100644 --- a/tests/functional/mulf16a.asm +++ b/tests/functional/mulf16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00h DEFB 80h @@ -28,23 +28,23 @@ _b: DEFB 00h DEFB 01h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b + 2) push hl ld hl, (_b) push hl ld de, 2 ld hl, 0 - call __MULF16 + call core.__MULF16 ld (_b), hl ld (_b + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,116 +56,122 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" ; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 ; Used with permission. ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') ; 64bit result is returned in H'L'H L B'C'A C + push namespace core __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP - ret ; result in h'l'hlb'c'ac + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" + push namespace core __MULF16: ; - ld a, d ; load sgn into a - ex af, af' ; saves it - call __ABS32 ; convert to positive - exx - pop hl ; Return address - pop de ; Low part - ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address - ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) - ex af, af' - xor d ; A register contains resulting sgn - ex af, af' - call __ABS32 ; convert to positive - call __MUL32_64START + ld a, d ; load sgn into a + ex af, af' ; saves it + call __ABS32 ; convert to positive + exx + pop hl ; Return address + pop de ; Low part + ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address + ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) + ex af, af' + xor d ; A register contains resulting sgn + ex af, af' + call __ABS32 ; convert to positive + call __MUL32_64START ; rounding (was not included in zx81) __ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 - ; result returned in dehl - ; input in h'l'hlb'c'ac - sla a ; result bit 47 to carry - exx - ld hl,0 ; ld does not change carry - adc hl,bc ; hl = hl + 0 + carry - push hl - exx - ld bc,0 - adc hl,bc ; hl = hl + 0 + carry - ex de, hl - pop hl ; rounded result in de.hl - ex af, af' ; recovers result sign - or a - jp m, __NEG32 ; if negative, negates it - ret + ; result returned in dehl + ; input in h'l'hlb'c'ac + sla a ; result bit 47 to carry + exx + ld hl,0 ; ld does not change carry + adc hl,bc ; hl = hl + 0 + carry + push hl + exx + ld bc,0 + adc hl,bc ; hl = hl + 0 + carry + ex de, hl + pop hl ; rounded result in de.hl + ex af, af' ; recovers result sign + or a + jp m, __NEG32 ; if negative, negates it + ret + pop namespace #line 26 "mulf16a.bas" END diff --git a/tests/functional/nir.asm b/tests/functional/nir.asm index 429a7e549..27af0cccd 100644 --- a/tests/functional/nir.asm +++ b/tests/functional/nir.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _sprite: DEFB 00 _lin: DEFB 00 _col: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: xor a ld (_sprite), a @@ -52,9 +52,9 @@ __LABEL__btiles: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/noheap.asm b/tests/functional/noheap.asm index 0add7c506..99db195cb 100644 --- a/tests/functional/noheap.asm +++ b/tests/functional/noheap.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 12345 - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,70 +46,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -139,49 +144,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -189,319 +200,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -556,469 +587,477 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 20 "noheap.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1041,76 +1080,79 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 21 "noheap.bas" END diff --git a/tests/functional/octal.asm b/tests/functional/octal.asm index a0ebfed44..d3decfdac 100644 --- a/tests/functional/octal.asm +++ b/tests/functional/octal.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 3Dh _b: DEFB 3Dh -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ongosub.asm b/tests/functional/ongosub.asm index 4dc666988..16e67db44 100644 --- a/tests/functional/ongosub.asm +++ b/tests/functional/ongosub.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,45 +8,45 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl ld a, (_a) add a, 2 - call __ON_GOSUB + call core.__ON_GOSUB ld hl, __LABEL1 push hl ld a, 1 - call __ON_GOSUB + call core.__ON_GOSUB ld hl, __LABEL2 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -58,26 +58,26 @@ __END_PROGRAM: __LABEL__40: ld hl, __LABEL3 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ret __LABEL__50: ld hl, __LABEL4 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ret __LABEL__60: ld hl, __LABEL5 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ret __LABEL__70: ld hl, __LABEL6 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ret __LABEL2: DEFW 0003h @@ -115,6 +115,7 @@ __LABEL1: ; ------------------------------------------------------ ; Implements ON .. GOTO ; ------------------------------------------------------ + push namespace core __ON_GOSUB: pop hl ex (sp), hl ; hl = beginning of table @@ -140,6 +141,7 @@ __ON_GOTO_START: ld h, (hl) ld l, a jp (hl) + pop namespace #line 85 "ongosub.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -148,70 +150,75 @@ __ON_GOTO_START: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -241,49 +248,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -291,319 +304,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -658,422 +691,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 86 "ongosub.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1200,9 +1236,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1210,37 +1247,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1250,134 +1288,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 87 "ongosub.bas" END diff --git a/tests/functional/ongoto.asm b/tests/functional/ongoto.asm index 2d4ed72d0..06a4e7c39 100644 --- a/tests/functional/ongoto.asm +++ b/tests/functional/ongoto.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,56 +8,56 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl ld a, (_a) inc a - call __ON_GOTO + call core.__ON_GOTO __LABEL__10: ld hl, __LABEL1 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL __LABEL__20: ld hl, __LABEL2 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL __LABEL__30: ld hl, __LABEL3 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, __LABEL4 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -93,6 +93,7 @@ __LABEL0: ; ------------------------------------------------------ ; Implements ON .. GOTO ; ------------------------------------------------------ + push namespace core __ON_GOSUB: pop hl ex (sp), hl ; hl = beginning of table @@ -118,6 +119,7 @@ __ON_GOTO_START: ld h, (hl) ld l, a jp (hl) + pop namespace #line 63 "ongoto.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -126,70 +128,75 @@ __ON_GOTO_START: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -219,49 +226,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -269,319 +282,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -636,422 +669,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 64 "ongoto.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1178,9 +1214,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1188,37 +1225,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1228,134 +1266,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 65 "ongoto.bas" END diff --git a/tests/functional/opt1_arr_at_init.asm b/tests/functional/opt1_arr_at_init.asm index 8612dc3bc..612f8dd2d 100644 --- a/tests/functional/opt1_arr_at_init.asm +++ b/tests/functional/opt1_arr_at_init.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _p: DEFW (_a.__DATA__ + 0) _a: @@ -271,14 +271,14 @@ __LABEL0: DEFW 0001h DEFW 000Bh DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_beep_const.asm b/tests/functional/opt1_beep_const.asm index 8f2e6cbaf..beecf14b5 100644 --- a/tests/functional/opt1_beep_const.asm +++ b/tests/functional/opt1_beep_const.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 1642 push hl ld hl, 261 - call __BEEPER + call core.__BEEPER ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,6 +46,7 @@ __END_PROGRAM: ; See http://www.wearmouth.demon.co.uk/zx82.htm#L03F8 ; Needs pitch on top of the stack ; HL = duration + push namespace core __BEEPER: ex de, hl pop hl @@ -54,5 +55,6 @@ __BEEPER: call 03B5h pop ix ret + pop namespace #line 21 "opt1_beep_const.bas" END diff --git a/tests/functional/opt1_beep_var.asm b/tests/functional/opt1_beep_var.asm index 7534dcb45..f08825258 100644 --- a/tests/functional/opt1_beep_var.asm +++ b/tests/functional/opt1_beep_var.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 81h DEFB 00h DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 000h ld de, 00000h ld bc, 00000h @@ -35,13 +35,13 @@ __MAIN_PROGRAM__: ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call BEEP + call core.BEEP ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,12 +56,13 @@ __END_PROGRAM: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -76,33 +77,36 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/beep.asm" + push namespace core BEEP: ; The beep command, as in BASIC - ; Duration in C,ED,LH (float) - ; Pitch in top of the stack - CALL __FPSTACK_PUSH - pop hl ; RET address - pop af - pop de - pop bc ; Recovers PITCH from the stack - push hl ; CALLEE, now ret addr in top of the stack - CALL __FPSTACK_PUSH ; Pitch onto the FP stack - push ix ; BEEP routine modifies IX. We have to preserve it - call 03F8h - pop ix - ret + ; Duration in C,ED,LH (float) + ; Pitch in top of the stack + CALL __FPSTACK_PUSH + pop hl ; RET address + pop af + pop de + pop bc ; Recovers PITCH from the stack + push hl ; CALLEE, now ret addr in top of the stack + CALL __FPSTACK_PUSH ; Pitch onto the FP stack + push ix ; BEEP routine modifies IX. We have to preserve it + call 03F8h + pop ix + ret + pop namespace #line 27 "opt1_beep_var.bas" END diff --git a/tests/functional/opt1_dim_arr_at1.asm b/tests/functional/opt1_dim_arr_at1.asm index 85744f289..16eb27e43 100644 --- a/tests/functional/opt1_dim_arr_at1.asm +++ b/tests/functional/opt1_dim_arr_at1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a.__DATA__ EQU 30000 @@ -68,8 +68,8 @@ __LABEL1: DEFW 0001h DEFW 0005h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a.__DATA__ ld (_c), hl ld hl, _b.__DATA__ @@ -77,9 +77,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_dim_arr_at2.asm b/tests/functional/opt1_dim_arr_at2.asm index fc185c752..8af814d89 100644 --- a/tests/functional/opt1_dim_arr_at2.asm +++ b/tests/functional/opt1_dim_arr_at2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00 _a.__DATA__ EQU 20000 @@ -38,8 +38,8 @@ __LABEL1: DEFW 0001h DEFW 0005h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a.__DATA__ + 13) ld (_c), a ld hl, _a.__DATA__ @@ -51,9 +51,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_dim_arr_at3.asm b/tests/functional/opt1_dim_arr_at3.asm index 6ee40bdd5..28290e632 100644 --- a/tests/functional/opt1_dim_arr_at3.asm +++ b/tests/functional/opt1_dim_arr_at3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _x: @@ -72,28 +72,28 @@ __LABEL1: DEFW 0001h DEFW 0005h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) push hl ld hl, (_x) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld (_c), hl ld hl, (_y) push hl ld hl, (_x) push hl ld hl, _b - call __ARRAY + call core.__ARRAY ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -120,81 +120,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -202,16 +205,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -230,6 +233,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 31 "opt1_dim_arr_at3.bas" END diff --git a/tests/functional/opt1_dim_arr_at4.asm b/tests/functional/opt1_dim_arr_at4.asm index 88cba6654..fe063b297 100644 --- a/tests/functional/opt1_dim_arr_at4.asm +++ b/tests/functional/opt1_dim_arr_at4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a.__DATA__ EQU 30000 @@ -68,8 +68,8 @@ __LABEL1: DEFW 0001h DEFW 0005h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a.__DATA__ ld de, 30 add hl, de @@ -81,9 +81,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_dim_arr_at5.asm b/tests/functional/opt1_dim_arr_at5.asm index c4d2fe476..ab0e00d18 100644 --- a/tests/functional/opt1_dim_arr_at5.asm +++ b/tests/functional/opt1_dim_arr_at5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a.__DATA__ EQU 16384 _a: DEFW __LABEL0 @@ -27,16 +27,16 @@ __LABEL0: DEFW 0001h DEFW 0020h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 255 ld (_a.__DATA__ + 0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_dim_arr_at_copy.asm b/tests/functional/opt1_dim_arr_at_copy.asm index b7db72da8..34b5dfeee 100644 --- a/tests/functional/opt1_dim_arr_at_copy.asm +++ b/tests/functional/opt1_dim_arr_at_copy.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a.__DATA__ EQU 16384 _a: DEFW __LABEL0 @@ -50,8 +50,8 @@ _b.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 16 ld b, h ld c, l @@ -61,9 +61,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_dim_arr_at_copy2.asm b/tests/functional/opt1_dim_arr_at_copy2.asm index 6d8a4f3ef..f2d9faea6 100644 --- a/tests/functional/opt1_dim_arr_at_copy2.asm +++ b/tests/functional/opt1_dim_arr_at_copy2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _test.a.__DATA__ EQU 16384 _test.a: DEFW __LABEL2 @@ -31,15 +31,15 @@ _test.a.__DATA__.__PTR__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,7 +60,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 16 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) push hl @@ -75,7 +75,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -157,6 +157,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -186,6 +187,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -251,9 +253,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -261,37 +264,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -304,90 +308,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -401,25 +407,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -434,6 +442,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -483,7 +492,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 51 "opt1_dim_arr_at_copy2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -553,94 +563,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 52 "opt1_dim_arr_at_copy2.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/opt1_dim_arr_at_copy3.asm b/tests/functional/opt1_dim_arr_at_copy3.asm index 391275215..04c347e8a 100644 --- a/tests/functional/opt1_dim_arr_at_copy3.asm +++ b/tests/functional/opt1_dim_arr_at_copy3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _test.a.__DATA__ EQU 16384 _test.a: DEFW __LABEL1 @@ -31,15 +31,15 @@ _test.a.__DATA__.__PTR__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -58,7 +58,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 16 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) push hl @@ -73,7 +73,7 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -155,6 +155,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -184,6 +185,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -249,9 +251,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -259,37 +262,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -302,90 +306,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -399,25 +405,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -432,6 +440,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -481,7 +490,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 49 "opt1_dim_arr_at_copy3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -551,94 +561,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 50 "opt1_dim_arr_at_copy3.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/opt1_dim_arr_at_copy4.asm b/tests/functional/opt1_dim_arr_at_copy4.asm index 7914cb854..d41326bcd 100644 --- a/tests/functional/opt1_dim_arr_at_copy4.asm +++ b/tests/functional/opt1_dim_arr_at_copy4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,11 +56,11 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 16 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld hl, -8 ld de, __LABEL1 ld bc, 16 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY ld l, (ix-6) ld h, (ix-5) push hl @@ -78,10 +78,10 @@ _test__leave: exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -163,6 +163,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -192,6 +193,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -257,9 +259,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -267,37 +270,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -310,90 +314,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -407,25 +413,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -440,6 +448,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -489,7 +498,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 65 "opt1_dim_arr_at_copy4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -559,94 +569,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 66 "opt1_dim_arr_at_copy4.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/opt1_dim_arr_global.asm b/tests/functional/opt1_dim_arr_global.asm index c2f1782e8..ea9d5b3d9 100644 --- a/tests/functional/opt1_dim_arr_global.asm +++ b/tests/functional/opt1_dim_arr_global.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,17 +8,17 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00 _a: @@ -35,22 +35,22 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 3 ld (_i), hl push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld a, (hl) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -77,81 +77,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -159,16 +162,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -187,7 +190,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 25 "opt1_dim_arr_global.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -196,70 +200,75 @@ TMP_ARR_PTR: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -289,49 +298,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -339,319 +354,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -706,537 +741,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 26 "opt1_dim_arr_global.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 27 "opt1_dim_arr_global.bas" END diff --git a/tests/functional/opt1_dim_arr_global2.asm b/tests/functional/opt1_dim_arr_global2.asm index 17dcb8bc8..adff01334 100644 --- a/tests/functional/opt1_dim_arr_global2.asm +++ b/tests/functional/opt1_dim_arr_global2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,17 +8,17 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -33,17 +33,17 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a.__DATA__ + 2) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,70 +60,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -153,49 +158,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -203,319 +214,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -570,537 +601,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 20 "opt1_dim_arr_global2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 21 "opt1_dim_arr_global2.bas" END diff --git a/tests/functional/opt1_dim_arr_global3.asm b/tests/functional/opt1_dim_arr_global3.asm index abc23c03e..705b66cb3 100644 --- a/tests/functional/opt1_dim_arr_global3.asm +++ b/tests/functional/opt1_dim_arr_global3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,17 +8,17 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -33,18 +33,18 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 7 ld (_a.__DATA__ + 2), a - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -61,70 +61,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -154,49 +159,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -204,319 +215,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -571,537 +602,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 21 "opt1_dim_arr_global3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 22 "opt1_dim_arr_global3.bas" END diff --git a/tests/functional/opt1_dim_arr_global4.asm b/tests/functional/opt1_dim_arr_global4.asm index 866b577a2..7482a26e6 100644 --- a/tests/functional/opt1_dim_arr_global4.asm +++ b/tests/functional/opt1_dim_arr_global4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,17 +8,17 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00 _a: @@ -35,27 +35,27 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 3 ld (_i), hl push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld (hl), 7 ld hl, (_i) push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld a, (hl) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -82,81 +82,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -164,16 +167,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -192,7 +195,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 30 "opt1_dim_arr_global4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -201,70 +205,75 @@ TMP_ARR_PTR: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -294,49 +303,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -344,319 +359,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -711,537 +746,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 31 "opt1_dim_arr_global4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 32 "opt1_dim_arr_global4.bas" END diff --git a/tests/functional/opt1_dim_arr_local.asm b/tests/functional/opt1_dim_arr_local.asm index 6c06010ef..79086c6c2 100644 --- a/tests/functional/opt1_dim_arr_local.asm +++ b/tests/functional/opt1_dim_arr_local.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,7 +54,7 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld hl, 2 ld (_i), hl push hl @@ -62,14 +62,14 @@ _test: pop hl ld de, -4 add hl, de - call __ARRAY + call core.__ARRAY ld a, (hl) _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -93,81 +93,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -175,16 +178,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -203,7 +206,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 51 "opt1_dim_arr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -280,6 +284,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -309,6 +314,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -374,9 +380,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -384,37 +391,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -427,90 +435,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -524,25 +534,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -557,6 +569,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -606,7 +619,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 52 "opt1_dim_arr_local.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -676,94 +690,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 53 "opt1_dim_arr_local.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/opt1_dim_arr_local2.asm b/tests/functional/opt1_dim_arr_local2.asm index c86534cd3..e6ebdd698 100644 --- a/tests/functional/opt1_dim_arr_local2.asm +++ b/tests/functional/opt1_dim_arr_local2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,21 +53,21 @@ _test: ld hl, -4 ld de, __LABEL0 ld bc, 6 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld l, (ix-2) ld h, (ix-1) inc hl inc hl inc hl ld a, (hl) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -149,6 +149,7 @@ _test__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -178,6 +179,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -243,9 +245,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -253,37 +256,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -296,90 +300,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -393,25 +399,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -426,6 +434,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -475,7 +484,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 50 "opt1_dim_arr_local2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -545,94 +555,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 51 "opt1_dim_arr_local2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -641,109 +653,118 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -751,319 +772,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1118,537 +1159,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 52 "opt1_dim_arr_local2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 53 "opt1_dim_arr_local2.bas" __LABEL0: diff --git a/tests/functional/opt1_dim_arr_local3.asm b/tests/functional/opt1_dim_arr_local3.asm index d34c7a3a2..011f151a9 100644 --- a/tests/functional/opt1_dim_arr_local3.asm +++ b/tests/functional/opt1_dim_arr_local3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -5 ld de, __LABEL0 ld bc, 6 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY push ix pop hl ld bc, -1 @@ -69,7 +69,7 @@ _test: pop hl ld de, -5 add hl, de - call __ARRAY + call core.__ARRAY ld a, (hl) push af ld l, (ix-3) @@ -83,7 +83,7 @@ _test__leave: exx ld l, (ix-3) ld h, (ix-2) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -107,81 +107,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -189,16 +192,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -217,7 +220,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 67 "opt1_dim_arr_local3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -294,6 +298,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -323,6 +328,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -388,9 +394,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -398,37 +405,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -441,90 +449,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -538,25 +548,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -571,6 +583,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -620,7 +633,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 68 "opt1_dim_arr_local3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -690,94 +704,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 69 "opt1_dim_arr_local3.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/opt1_dim_arr_local4.asm b/tests/functional/opt1_dim_arr_local4.asm index 3d4fdd25d..688246188 100644 --- a/tests/functional/opt1_dim_arr_local4.asm +++ b/tests/functional/opt1_dim_arr_local4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _test: ld hl, -5 ld de, __LABEL0 ld bc, 6 - call __ALLOC_LOCAL_ARRAY + call core.__ALLOC_LOCAL_ARRAY push ix pop hl ld bc, -1 @@ -69,7 +69,7 @@ _test: pop hl ld de, -5 add hl, de - call __ARRAY + call core.__ARRAY ld (hl), 7 ld a, (ix-1) ld l, a @@ -79,14 +79,14 @@ _test: pop hl ld de, -5 add hl, de - call __ARRAY + call core.__ARRAY ld a, (hl) _test__leave: ex af, af' exx ld l, (ix-3) ld h, (ix-2) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -110,81 +110,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -192,16 +195,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -220,7 +223,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 70 "opt1_dim_arr_local4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -297,6 +301,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -326,6 +331,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -391,9 +397,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -401,37 +408,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -444,90 +452,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -541,25 +551,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -574,6 +586,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -623,7 +636,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 71 "opt1_dim_arr_local4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -693,94 +707,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "opt1_dim_arr_local4.bas" __LABEL0: DEFB 00h diff --git a/tests/functional/opt1_dim_at_defval.asm b/tests/functional/opt1_dim_at_defval.asm index 5f8b2f4e1..0099d5d14 100644 --- a/tests/functional/opt1_dim_at_defval.asm +++ b/tests/functional/opt1_dim_at_defval.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _q EQU 0 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_endtest.asm b/tests/functional/opt1_endtest.asm index 32a42f5f9..a1ee25511 100644 --- a/tests/functional/opt1_endtest.asm +++ b/tests/functional/opt1_endtest.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _N: DEFB 39h DEFB 30h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_N) ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_len.asm b/tests/functional/opt1_len.asm index c4480c01a..4b9804e9e 100644 --- a/tests/functional/opt1_len.asm +++ b/tests/functional/opt1_len.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call INKEY +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.INKEY push hl - call __STRLEN + call core.__STRLEN ex (sp), hl - call __MEM_FREE + call core.__MEM_FREE pop hl ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -173,9 +173,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -183,37 +184,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -223,94 +225,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 24 "opt1_len.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" ; INKEY Function @@ -380,6 +384,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -409,6 +414,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -421,146 +427,152 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" + push namespace core INKEY: - PROC - LOCAL __EMPTY_INKEY - LOCAL KEY_SCAN - LOCAL KEY_TEST - LOCAL KEY_CODE - ld bc, 3 ; 1 char length string - call __MEM_ALLOC - ld a, h - or l - ret z ; Return if NULL (No memory) - push hl ; Saves memory pointer - call KEY_SCAN - jp nz, __EMPTY_INKEY - call KEY_TEST - jp nc, __EMPTY_INKEY - dec d ; D is expected to be FLAGS so set bit 3 $FF - ; 'L' Mode so no keywords. - ld e, a ; main key to A - ; C is MODE 0 'KLC' from above still. - call KEY_CODE ; routine K-DECODE - pop hl - ld (hl), 1 - inc hl - ld (hl), 0 - inc hl - ld (hl), a - dec hl - dec hl ; HL Points to string result - ret + PROC + LOCAL __EMPTY_INKEY + LOCAL KEY_SCAN + LOCAL KEY_TEST + LOCAL KEY_CODE + ld bc, 3 ; 1 char length string + call __MEM_ALLOC + ld a, h + or l + ret z ; Return if NULL (No memory) + push hl ; Saves memory pointer + call KEY_SCAN + jp nz, __EMPTY_INKEY + call KEY_TEST + jp nc, __EMPTY_INKEY + dec d ; D is expected to be FLAGS so set bit 3 $FF + ; 'L' Mode so no keywords. + ld e, a ; main key to A + ; C is MODE 0 'KLC' from above still. + call KEY_CODE ; routine K-DECODE + pop hl + ld (hl), 1 + inc hl + ld (hl), 0 + inc hl + ld (hl), a + dec hl + dec hl ; HL Points to string result + ret __EMPTY_INKEY: - pop hl - xor a - ld (hl), a - inc hl - ld (hl), a - dec hl - ret + pop hl + xor a + ld (hl), a + inc hl + ld (hl), a + dec hl + ret KEY_SCAN EQU 028Eh KEY_TEST EQU 031Eh KEY_CODE EQU 0333h - ENDP + ENDP + pop namespace #line 25 "opt1_len.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 26 "opt1_len.bas" END diff --git a/tests/functional/opt1_nolabel.asm b/tests/functional/opt1_nolabel.asm index 1afe79fcb..ed9feda6d 100644 --- a/tests/functional/opt1_nolabel.asm +++ b/tests/functional/opt1_nolabel.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 3 "opt1_nolabel.bas" ld hl, mygod #line 5 "opt1_nolabel.bas" @@ -32,9 +32,9 @@ __LABEL__finish: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt1_usr.asm b/tests/functional/opt1_usr.asm index 4c026a681..1e65c7d6d 100644 --- a/tests/functional/opt1_usr.asm +++ b/tests/functional/opt1_usr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld l, a ld h, 0 - call USR + call core.USR ld a, l ld (_a), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,24 +52,28 @@ __END_PROGRAM: ; The incoming parameter is HL (Address to JUMP) ; #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/usr.asm" + push namespace core USR: - call CALL_HL - ld h, b - ld l, c - ret + call CALL_HL + ld h, b + ld l, c + ret + pop namespace #line 23 "opt1_usr.bas" END diff --git a/tests/functional/opt2_ato4.asm b/tests/functional/opt2_ato4.asm index ebbc83119..d9770f0cd 100644 --- a/tests/functional/opt2_ato4.asm +++ b/tests/functional/opt2_ato4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _toloX: DEFB 00, 00 _toloY: @@ -26,8 +26,8 @@ _doorX: DEFB 00 _doorY: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_toloX) ld a, (hl) cp 3 @@ -87,9 +87,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_ato5.asm b/tests/functional/opt2_ato5.asm index ebbc83119..d9770f0cd 100644 --- a/tests/functional/opt2_ato5.asm +++ b/tests/functional/opt2_ato5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _toloX: DEFB 00, 00 _toloY: @@ -26,8 +26,8 @@ _doorX: DEFB 00 _doorY: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_toloX) ld a, (hl) cp 3 @@ -87,9 +87,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_dim_arr_at1.asm b/tests/functional/opt2_dim_arr_at1.asm index 9f642a2f1..25094c6b8 100644 --- a/tests/functional/opt2_dim_arr_at1.asm +++ b/tests/functional/opt2_dim_arr_at1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a.__DATA__ EQU 30000 @@ -29,16 +29,16 @@ __LABEL0: DEFW 0001h DEFW 0006h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_c) ld (_a.__DATA__ + 28), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_dim_at.asm b/tests/functional/opt2_dim_at.asm index 6f21f3ef9..9ceb48e82 100644 --- a/tests/functional/opt2_dim_at.asm +++ b/tests/functional/opt2_dim_at.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _UDGptr EQU 23675 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 65000 ld (_UDGptr), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_fastcall_func.asm b/tests/functional/opt2_fastcall_func.asm index 03390c9e1..66d9b0011 100644 --- a/tests/functional/opt2_fastcall_func.asm +++ b/tests/functional/opt2_fastcall_func.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,19 +8,19 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _c1 ld (0), a call _c2 @@ -28,9 +28,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,8 +44,8 @@ _test: ld ix, 0 add ix, sp ld a, (ix+5) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld a, (ix+5) inc a _test__leave: @@ -90,70 +90,75 @@ _c2__leave: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -183,49 +188,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -233,319 +244,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -600,537 +631,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 64 "opt2_fastcall_func.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 65 "opt2_fastcall_func.bas" END diff --git a/tests/functional/opt2_fastcall_sub.asm b/tests/functional/opt2_fastcall_sub.asm index 06b192961..1068aa840 100644 --- a/tests/functional/opt2_fastcall_sub.asm +++ b/tests/functional/opt2_fastcall_sub.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _c1 call _c2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_func_call.asm b/tests/functional/opt2_func_call.asm index c51f7bc8b..1a9f2f5fd 100644 --- a/tests/functional/opt2_func_call.asm +++ b/tests/functional/opt2_func_call.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _c1 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,8 +42,8 @@ _test: ld ix, 0 add ix, sp ld a, (ix+5) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld a, (ix+5) inc a _test__leave: @@ -68,70 +68,75 @@ _c1__leave: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -161,49 +166,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -211,319 +222,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -578,537 +609,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 42 "opt2_func_call.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 43 "opt2_func_call.bas" END diff --git a/tests/functional/opt2_global_array.asm b/tests/functional/opt2_global_array.asm index 2301e3b68..b14cfc963 100644 --- a/tests/functional/opt2_global_array.asm +++ b/tests/functional/opt2_global_array.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _Init ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_global_array2.asm b/tests/functional/opt2_global_array2.asm index 08237efcb..3118856cc 100644 --- a/tests/functional/opt2_global_array2.asm +++ b/tests/functional/opt2_global_array2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _myArray2: DEFW __LABEL0 _myArray2.__DATA__.__PTR__: @@ -32,15 +32,15 @@ _myArray2.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _Init ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_goto_in_func.asm b/tests/functional/opt2_goto_in_func.asm index d29c7ca38..64447b51c 100644 --- a/tests/functional/opt2_goto_in_func.asm +++ b/tests/functional/opt2_goto_in_func.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_ifband.asm b/tests/functional/opt2_ifband.asm index cd9be472c..8d1234bdf 100644 --- a/tests/functional/opt2_ifband.asm +++ b/tests/functional/opt2_ifband.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) and 1 jp z, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_ifbor.asm b/tests/functional/opt2_ifbor.asm index 8c14fb60b..69a2e5ec4 100644 --- a/tests/functional/opt2_ifbor.asm +++ b/tests/functional/opt2_ifbor.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) or 1 jp z, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_ifbor2.asm b/tests/functional/opt2_ifbor2.asm index 40d2d819f..899b24368 100644 --- a/tests/functional/opt2_ifbor2.asm +++ b/tests/functional/opt2_ifbor2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _x ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_ifbyte.asm b/tests/functional/opt2_ifbyte.asm index 6051d36e6..a87b1c655 100644 --- a/tests/functional/opt2_ifbyte.asm +++ b/tests/functional/opt2_ifbyte.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) sub 64 jp nz, __LABEL1 @@ -31,9 +31,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_ifthen.asm b/tests/functional/opt2_ifthen.asm index 8d2a1354e..d64b36c4f 100644 --- a/tests/functional/opt2_ifthen.asm +++ b/tests/functional/opt2_ifthen.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _toloX: DEFB 00, 00 _toloY: @@ -26,8 +26,8 @@ _doorX: DEFB 00 _doorY: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_toloX) ld a, (hl) cp 3 @@ -80,9 +80,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_incdec_byte.asm b/tests/functional/opt2_incdec_byte.asm index ece42350d..6febc5e83 100644 --- a/tests/functional/opt2_incdec_byte.asm +++ b/tests/functional/opt2_incdec_byte.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a inc (hl) ld hl, _a @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_include_unused.asm b/tests/functional/opt2_include_unused.asm index d29c7ca38..64447b51c 100644 --- a/tests/functional/opt2_include_unused.asm +++ b/tests/functional/opt2_include_unused.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_infinite_loop.asm b/tests/functional/opt2_infinite_loop.asm index cc3e0539c..aba19a5d8 100644 --- a/tests/functional/opt2_infinite_loop.asm +++ b/tests/functional/opt2_infinite_loop.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _kill: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_label_ref_in_func1.asm b/tests/functional/opt2_label_ref_in_func1.asm index bc50d224c..b62c157a4 100644 --- a/tests/functional/opt2_label_ref_in_func1.asm +++ b/tests/functional/opt2_label_ref_in_func1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (__LABEL__label) + (1) ld (0), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_label_ref_in_func2.asm b/tests/functional/opt2_label_ref_in_func2.asm index 2605f2655..6ee96e7d3 100644 --- a/tests/functional/opt2_label_ref_in_func2.asm +++ b/tests/functional/opt2_label_ref_in_func2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (__LABEL__label) + (1) ld (0), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_labelinfunc.asm b/tests/functional/opt2_labelinfunc.asm index 8246bdc17..b0212809a 100644 --- a/tests/functional/opt2_labelinfunc.asm +++ b/tests/functional/opt2_labelinfunc.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld (__LABEL__label1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_labelinfunc3.asm b/tests/functional/opt2_labelinfunc3.asm index 8246bdc17..b0212809a 100644 --- a/tests/functional/opt2_labelinfunc3.asm +++ b/tests/functional/opt2_labelinfunc3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld (__LABEL__label1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_labelinfunc4.asm b/tests/functional/opt2_labelinfunc4.asm index a4b16fef7..22940060e 100644 --- a/tests/functional/opt2_labelinfunc4.asm +++ b/tests/functional/opt2_labelinfunc4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld (__LABEL__label1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_labelinfunc5.asm b/tests/functional/opt2_labelinfunc5.asm index a4b16fef7..22940060e 100644 --- a/tests/functional/opt2_labelinfunc5.asm +++ b/tests/functional/opt2_labelinfunc5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 ld (__LABEL__label1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_letsubstr_not_used.asm b/tests/functional/opt2_letsubstr_not_used.asm index d29c7ca38..64447b51c 100644 --- a/tests/functional/opt2_letsubstr_not_used.asm +++ b/tests/functional/opt2_letsubstr_not_used.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_localu8.asm b/tests/functional/opt2_localu8.asm index 95436fba1..b1fee9486 100644 --- a/tests/functional/opt2_localu8.asm +++ b/tests/functional/opt2_localu8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 253 push af ld a, 2 @@ -28,9 +28,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_pstr.asm b/tests/functional/opt2_pstr.asm index e9a7b0349..ae730b954 100644 --- a/tests/functional/opt2_pstr.asm +++ b/tests/functional/opt2_pstr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _PRINT642 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _PRINT642__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -194,9 +194,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -204,37 +205,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -244,94 +246,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 47 "opt2_pstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -397,6 +401,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -426,6 +431,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -438,124 +444,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 48 "opt2_pstr.bas" END diff --git a/tests/functional/opt2_recurse_filter2.asm b/tests/functional/opt2_recurse_filter2.asm index 5f6dfda7a..36579d3b3 100644 --- a/tests/functional/opt2_recurse_filter2.asm +++ b/tests/functional/opt2_recurse_filter2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt2_snake_es.asm b/tests/functional/opt2_snake_es.asm index cb1a2f352..9a306c61a 100644 --- a/tests/functional/opt2_snake_es.asm +++ b/tests/functional/opt2_snake_es.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _ny: DEFB 00 _cx: @@ -154,8 +154,8 @@ __LABEL0: DEFW 0001h DEFW 000Bh DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_cx) add a, 2 ld l, a @@ -167,7 +167,7 @@ __MAIN_PROGRAM__: ld h, 0 push hl ld hl, _y - call __ARRAY + call core.__ARRAY ld a, (_cy) add a, (hl) ld (_ny), a @@ -175,9 +175,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -204,81 +204,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -286,16 +289,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -314,6 +317,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 33 "opt2_snake_es.bas" END diff --git a/tests/functional/opt2_unused_var.asm b/tests/functional/opt2_unused_var.asm index 4c6e54888..218f2c0b8 100644 --- a/tests/functional/opt2_unused_var.asm +++ b/tests/functional/opt2_unused_var.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _Check ld hl, 0 - call __PAUSE + call core.__PAUSE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -70,9 +70,11 @@ _Check__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/pause.asm" ; The PAUSE statement (Calling the ROM) + push namespace core __PAUSE: - ld b, h + ld b, h ld c, l jp 1F3Dh ; PAUSE_1 + pop namespace #line 50 "opt2_unused_var.bas" END diff --git a/tests/functional/opt2_unused_var1.asm b/tests/functional/opt2_unused_var1.asm index d29c7ca38..64447b51c 100644 --- a/tests/functional/opt2_unused_var1.asm +++ b/tests/functional/opt2_unused_var1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_17.asm b/tests/functional/opt3_17.asm index 532ade1bb..4df2ffeda 100644 --- a/tests/functional/opt3_17.asm +++ b/tests/functional/opt3_17.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (23672), a ld (23673), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_OPT27wws2.asm b/tests/functional/opt3_OPT27wws2.asm index b1cc7edaf..73d8b921b 100644 --- a/tests/functional/opt3_OPT27wws2.asm +++ b/tests/functional/opt3_OPT27wws2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _n: DEFB 00, 00 _yenem: @@ -58,31 +58,31 @@ _incyenem.__DATA__: __LABEL1: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_n) push hl ld hl, _yenem - call __ARRAY + call core.__ARRAY ld a, (hl) push af ld hl, (_n) push hl ld hl, _incyenem - call __ARRAY + call core.__ARRAY pop af add a, (hl) push af ld hl, (_n) push hl ld hl, _yenem - call __ARRAY + call core.__ARRAY pop af ld (hl), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -109,81 +109,84 @@ __END_PROGRAM: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -191,16 +194,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -219,6 +222,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 34 "opt3_OPT27wws2.bas" END diff --git a/tests/functional/opt3_asmexpr.asm b/tests/functional/opt3_asmexpr.asm index ae2d1dd0d..2dfca744b 100644 --- a/tests/functional/opt3_asmexpr.asm +++ b/tests/functional/opt3_asmexpr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "opt3_asmexpr.bas" ld de,56815-(8*41) #line 4 "opt3_asmexpr.bas" ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_ato4.asm b/tests/functional/opt3_ato4.asm index 8e9e0e2c4..253baba3e 100644 --- a/tests/functional/opt3_ato4.asm +++ b/tests/functional/opt3_ato4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _toloX: DEFB 00, 00 _toloY: @@ -26,8 +26,8 @@ _doorX: DEFB 00 _doorY: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_toloX) ld a, (hl) cp 3 @@ -83,9 +83,9 @@ __LABEL2: ld (_doorX), a __LABEL1: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_atohl_a.asm b/tests/functional/opt3_atohl_a.asm index 71d6c3d2b..536bf7e4b 100644 --- a/tests/functional/opt3_atohl_a.asm +++ b/tests/functional/opt3_atohl_a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _dw1: DEFB 00, 00 _i: DEFB 00, 00 _g: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_g) push af ld a, (_i) @@ -33,9 +33,9 @@ __MAIN_PROGRAM__: ld hl, (_dw1) call _putTile10x8Box__leave ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_atolo1.asm b/tests/functional/opt3_atolo1.asm index 265163bb6..4b594e94d 100644 --- a/tests/functional/opt3_atolo1.asm +++ b/tests/functional/opt3_atolo1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "opt3_atolo1.bas" ld a,(bc) ld h, a @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: call 0x000 #line 9 "opt3_atolo1.bas" ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_atolo4.asm b/tests/functional/opt3_atolo4.asm index 493873f35..f5a5a5474 100644 --- a/tests/functional/opt3_atolo4.asm +++ b/tests/functional/opt3_atolo4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _kkk: DEFB 00, 00 _poma: DEFB 00 _pomb: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_kkk) ld a, (hl) ld (_poma), a @@ -34,9 +34,9 @@ __MAIN_PROGRAM__: ld a, (hl) ld (_pomb), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_atoloinc.asm b/tests/functional/opt3_atoloinc.asm index 2a93fdf7b..cee659172 100644 --- a/tests/functional/opt3_atoloinc.asm +++ b/tests/functional/opt3_atoloinc.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00 _key: @@ -28,8 +28,8 @@ _doorid: DEFB 00 _nfires: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_level), a ld (_key), a @@ -45,9 +45,9 @@ __MAIN_PROGRAM__: ld hl, _nfires inc (hl) ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_dark01.asm b/tests/functional/opt3_dark01.asm index 4c004e381..1887b34b3 100644 --- a/tests/functional/opt3_dark01.asm +++ b/tests/functional/opt3_dark01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _bPtr: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 32768 ld (_bPtr), hl jp __LABEL0 @@ -42,9 +42,9 @@ __LABEL0: sbc hl, de jp nc, __LABEL3 ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_data2.asm b/tests/functional/opt3_data2.asm index 36575d91b..ebb007343 100644 --- a/tests/functional/opt3_data2.asm +++ b/tests/functional/opt3_data2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 _a: @@ -44,21 +44,21 @@ _a.__DATA__: __LABEL5: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_i), a jp __LABEL0 __LABEL3: ld a, 3 - call __READ + call core.__READ push af ld a, (_i) ld l, a ld h, 0 push hl ld hl, _a - call __ARRAY + call core.__ARRAY pop af ld (hl), a ld a, (_i) @@ -66,10 +66,10 @@ __LABEL3: ld h, 0 push hl ld hl, _a - call __ARRAY + call core.__ARRAY ld a, (hl) - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, _i inc (hl) __LABEL0: @@ -78,9 +78,9 @@ __LABEL0: cp h jp nc, __LABEL3 ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -92,7 +92,7 @@ __END_PROGRAM: ___DATA__FUNCPTR__0: ld a, (_i) ld h, 6 - call __MUL8_FAST + call core.__MUL8_FAST ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: @@ -157,81 +157,84 @@ __DATA__END: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -239,16 +242,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -267,17 +270,19 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 96 "opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -311,8 +316,9 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 97 "opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -321,70 +327,75 @@ __MUL8B: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -414,49 +425,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -464,319 +481,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -831,537 +868,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 98 "opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 99 "opt3_data2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -1507,9 +1553,10 @@ __PRINTU_LOOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1517,37 +1564,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -1560,148 +1608,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -1712,91 +1767,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1813,124 +1872,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -1938,18 +2003,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -2019,94 +2085,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -2118,6 +2186,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2394,5 +2463,6 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 100 "opt3_data2.bas" END diff --git a/tests/functional/opt3_einar.asm b/tests/functional/opt3_einar.asm index e4c24f604..760f15505 100644 --- a/tests/functional/opt3_einar.asm +++ b/tests/functional/opt3_einar.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _x2 ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,14 +53,14 @@ _x2: jp nc, __LABEL0 ld hl, __LABEL2 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL jp _x2__leave __LABEL0: ld hl, __LABEL3 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL _x2__leave: ld sp, ix pop ix @@ -82,70 +82,75 @@ __LABEL3: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -175,49 +180,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -225,319 +236,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -592,422 +623,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 51 "opt3_einar.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1134,9 +1168,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1144,37 +1179,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1184,134 +1220,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 52 "opt3_einar.bas" END diff --git a/tests/functional/opt3_einar04.asm b/tests/functional/opt3_einar04.asm index d86e35e6b..088076275 100644 --- a/tests/functional/opt3_einar04.asm +++ b/tests/functional/opt3_einar04.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: ld a, 201 ld (50000), a @@ -27,9 +27,9 @@ __LABEL__10: ld a, 1 call _test ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_einar05.asm b/tests/functional/opt3_einar05.asm index 50553977d..aabcbdcb3 100644 --- a/tests/functional/opt3_einar05.asm +++ b/tests/functional/opt3_einar05.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 2 "opt3_einar05.bas" call $fc12 di @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ei #line 9 "opt3_einar05.bas" ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_einar06.asm b/tests/functional/opt3_einar06.asm index fe5f74657..9c438ae06 100644 --- a/tests/functional/opt3_einar06.asm +++ b/tests/functional/opt3_einar06.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_endtest.asm b/tests/functional/opt3_endtest.asm index 3c50eb2e7..3d2d2c1a4 100644 --- a/tests/functional/opt3_endtest.asm +++ b/tests/functional/opt3_endtest.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _N: DEFB 39h DEFB 30h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld bc, (_N) -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_fixed.asm b/tests/functional/opt3_fixed.asm index 6a2eb1a0c..bdcfd0587 100644 --- a/tests/functional/opt3_fixed.asm +++ b/tests/functional/opt3_fixed.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00, 00, 00 _dx: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_x) ld de, (_x + 2) ld bc, (_dx) @@ -38,9 +38,9 @@ __MAIN_PROGRAM__: xor a ld (hl), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_gogogoto.asm b/tests/functional/opt3_gogogoto.asm index 86fd485ea..f0d95757d 100644 --- a/tests/functional/opt3_gogogoto.asm +++ b/tests/functional/opt3_gogogoto.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL__20: jp __LABEL__20 diff --git a/tests/functional/opt3_gotogosub.asm b/tests/functional/opt3_gotogosub.asm index 09b01fde8..53f59b413 100644 --- a/tests/functional/opt3_gotogosub.asm +++ b/tests/functional/opt3_gotogosub.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: call __LABEL__50 __LABEL__20: @@ -29,9 +29,9 @@ __LABEL__20: ld (_a), a __LABEL__25: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_gotogoto.asm b/tests/functional/opt3_gotogoto.asm index 8940f847b..90f6bf994 100644 --- a/tests/functional/opt3_gotogoto.asm +++ b/tests/functional/opt3_gotogoto.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: jp __LABEL__50 __LABEL__20: @@ -36,9 +36,9 @@ __LABEL__50: ld hl, _a inc (hl) ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_haplo01.asm b/tests/functional/opt3_haplo01.asm index f85749ec9..46077e0a2 100644 --- a/tests/functional/opt3_haplo01.asm +++ b/tests/functional/opt3_haplo01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 19 ld (_a), hl ex de, hl @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: add hl, de ld (_a), hl ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_haplo05.asm b/tests/functional/opt3_haplo05.asm index c61df865e..b1f4bbb82 100644 --- a/tests/functional/opt3_haplo05.asm +++ b/tests/functional/opt3_haplo05.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _dataSprite: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 4 ld (31744), a ld a, 83 @@ -35,7 +35,7 @@ __MAIN_PROGRAM__: add hl, de ld a, (hl) ld h, 6 - call __MUL8_FAST + call core.__MUL8_FAST pop hl ld (hl), a ld hl, (_dataSprite) @@ -99,9 +99,9 @@ __MAIN_PROGRAM__: add hl, de ld (hl), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -112,14 +112,15 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm" + push namespace core __MUL8: ; Performs 8bit x 8bit multiplication - PROC - ;LOCAL __MUL8A - LOCAL __MUL8LOOP - LOCAL __MUL8B - ; 1st operand (byte) in A, 2nd operand into the stack (AF) - pop hl ; return address - ex (sp), hl ; CALLE convention + PROC + ;LOCAL __MUL8A + LOCAL __MUL8LOOP + LOCAL __MUL8B + ; 1st operand (byte) in A, 2nd operand into the stack (AF) + pop hl ; return address + ex (sp), hl ; CALLE convention ;;__MUL8_FAST: ; __FASTCALL__ entry ;; ld e, a ;; ld d, 0 @@ -153,7 +154,8 @@ __MUL8LOOP: add a, h __MUL8B: djnz __MUL8LOOP - ret ; result = HL - ENDP + ret ; result = HL + ENDP + pop namespace #line 91 "opt3_haplo05.bas" END diff --git a/tests/functional/opt3_haplo06.asm b/tests/functional/opt3_haplo06.asm index 95d95ca0b..dbecc3fa0 100644 --- a/tests/functional/opt3_haplo06.asm +++ b/tests/functional/opt3_haplo06.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _y: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) ld a, (_a) or (hl) @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: or (hl) ld (_a), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_haplobug.asm b/tests/functional/opt3_haplobug.asm index a53da1ff0..fa95b16f6 100644 --- a/tests/functional/opt3_haplobug.asm +++ b/tests/functional/opt3_haplobug.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _dataSprite: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_dataSprite) ld de, 26 add hl, de @@ -55,9 +55,9 @@ __MAIN_PROGRAM__: xor a ld (hl), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_ifgotoelse.asm b/tests/functional/opt3_ifgotoelse.asm index 8e125b4fc..23004bd1c 100644 --- a/tests/functional/opt3_ifgotoelse.asm +++ b/tests/functional/opt3_ifgotoelse.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) dec a jp nz, __LABEL0 @@ -34,9 +34,9 @@ __LABEL0: ld (_a), a __LABEL__10: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_inout.asm b/tests/functional/opt3_inout.asm index ad3608e71..a92bb0344 100644 --- a/tests/functional/opt3_inout.asm +++ b/tests/functional/opt3_inout.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld bc, 32768 out (c), a @@ -32,9 +32,9 @@ __MAIN_PROGRAM__: ld (_a), a ld (0), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_lcd5.asm b/tests/functional/opt3_lcd5.asm index 358255082..ddda9b2d7 100644 --- a/tests/functional/opt3_lcd5.asm +++ b/tests/functional/opt3_lcd5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,54 +8,54 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00, 00, 00, 00 _y: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 3 push af ld a, (_y) ld de, (_y + 1) ld bc, (_y + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call __FTOU32REG + call core.__FTOU32REG push hl call _SetField ld a, (_y) ld de, (_y + 1) ld bc, (_y + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, (_x) ld de, (_x + 1) ld bc, (_x + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af call _ScanNear __LABEL__chessboard: __LABEL__overlay: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -74,12 +74,12 @@ _ScanField: ld h, (ix+5) ex de, hl ld hl, 0 - call __LEI16 + call core.__LEI16 push af ld l, (ix+4) ld h, (ix+5) ld de, 8 - call __LTI16 + call core.__LTI16 ld h, a pop af or a @@ -91,7 +91,7 @@ __LABEL6: ld h, (ix+7) ex de, hl ld hl, 0 - call __LEI16 + call core.__LEI16 ld h, a pop af or a @@ -102,7 +102,7 @@ __LABEL7: ld l, (ix+6) ld h, (ix+7) ld de, 8 - call __LTI16 + call core.__LTI16 ld h, a pop af or a @@ -378,77 +378,80 @@ _ScanNear__leave: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -465,13 +468,15 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 354 "opt3_lcd5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei16.asm" + push namespace core __LEI16: PROC LOCAL checkParity @@ -488,11 +493,13 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 355 "opt3_lcd5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -510,9 +517,11 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti16.asm" + push namespace core __LTI16: ; Test 8 bit values HL < DE - ; Returns result in A: 0 = False, !0 = True + ; Returns result in A: 0 = False, !0 = True PROC LOCAL checkParity or a @@ -526,5 +535,6 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 356 "opt3_lcd5.bas" END diff --git a/tests/functional/opt3_lcd6.asm b/tests/functional/opt3_lcd6.asm index ffdb2ddcd..db0adc7de 100644 --- a/tests/functional/opt3_lcd6.asm +++ b/tests/functional/opt3_lcd6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__chessboard: __LABEL__overlay: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_lcd_o3_crash.asm b/tests/functional/opt3_lcd_o3_crash.asm index 062ff91d8..7bf71751d 100644 --- a/tests/functional/opt3_lcd_o3_crash.asm +++ b/tests/functional/opt3_lcd_o3_crash.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _Drawscreen __LABEL__Shoottable1: __LABEL__Shoottable2: __LABEL__UDGs01: __LABEL__Buffer: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_ldhlhl.asm b/tests/functional/opt3_ldhlhl.asm index ca1121e6e..685aab782 100644 --- a/tests/functional/opt3_ldhlhl.asm +++ b/tests/functional/opt3_ldhlhl.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 3 "opt3_ldhlhl.bas" ld hl, 0 ld hl, 0 #line 6 "opt3_ldhlhl.bas" ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_nextbuild.asm b/tests/functional/opt3_nextbuild.asm index bd537acd5..1fd04c148 100644 --- a/tests/functional/opt3_nextbuild.asm +++ b/tests/functional/opt3_nextbuild.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 push hl ld a, 16 @@ -43,9 +43,9 @@ __MAIN_PROGRAM__: push hl call _UpdateSprite ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_proc0.asm b/tests/functional/opt3_proc0.asm index 2fac27319..a569e0126 100644 --- a/tests/functional/opt3_proc0.asm +++ b/tests/functional/opt3_proc0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _p ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt3_sp.asm b/tests/functional/opt3_sp.asm index b9b43549c..44400e0ed 100644 --- a/tests/functional/opt3_sp.asm +++ b/tests/functional/opt3_sp.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 10 push hl call _test ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,21 +51,21 @@ _test: ld l, (ix+4) ld h, (ix+5) ld de, 0 - call __U32TOFREG + call core.__U32TOFREG ld hl, -5 - call __PSTOREF + call core.__PSTOREF push ix pop hl ld de, -5 add hl, de - call __PLOADF + call core.__PLOADF ld hl, -10 - call __PSTOREF + call core.__PSTOREF push ix pop hl ld de, -10 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af @@ -73,10 +73,10 @@ _test: pop hl ld de, -10 add hl, de - call __PLOADF - call __ADDF + call core.__PLOADF + call core.__ADDF ld hl, -15 - call __PSTOREF + call core.__PSTOREF _test__leave: ld sp, ix pop ix @@ -91,12 +91,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -111,19 +112,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -133,13 +135,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 68 "opt3_sp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -151,6 +155,7 @@ __ADDF: ; Addition ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -161,22 +166,25 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 69 "opt3_sp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stores FP number in A ED CB at location HL+IX @@ -184,133 +192,141 @@ __PLOADF: ; IX = Stack Frame ; A ED CB = FP Number #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stored a float number in A ED CB into the address pointed by IX + HL + push namespace core __PSTOREF: - push de + push de ex de, hl ; DE <- HL push ix - pop hl ; HL <- IX + pop hl ; HL <- IX add hl, de ; HL <- IX + DE - pop de + pop de jp __STOREF + pop namespace #line 70 "opt3_sp.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 71 "opt3_sp.bas" END diff --git a/tests/functional/opt3_tolosob.asm b/tests/functional/opt3_tolosob.asm index 57fde7f82..04bfcb50f 100644 --- a/tests/functional/opt3_tolosob.asm +++ b/tests/functional/opt3_tolosob.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _toloTimer: DEFB 00, 00 _toloStatus: DEFB 00, 00 _sobando: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__inicio: ld de, 0 ld hl, (_toloTimer) + call core.__EQ16 or a - sbc hl, de - jp nz, __LABEL__inicio + jp z, __LABEL__inicio ld a, 1 ld (_sobando), a sub 2 @@ -50,9 +50,9 @@ __LABEL3: jp nz, __LABEL__inicio ld de, 10 ld hl, (_toloTimer) + call core.__EQ16 or a - sbc hl, de - jp nz, __LABEL__inicio + jp z, __LABEL__inicio ld hl, (_toloStatus) ld a, (hl) and 2 @@ -63,12 +63,14 @@ __LABEL__pontolosobando: jp __LABEL__inicio ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/eq16.asm" + push namespace core __EQ16: ; Test if 16bit values HL == DE - ; Returns result in A: 0 = False, FF = True - xor a ; Reset carry flag - sbc hl, de - ret nz - inc a - ret + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace #line 38 "opt3_tolosob.bas" END diff --git a/tests/functional/opt3_xorxor.asm b/tests/functional/opt3_xorxor.asm index ff1c38e91..01ef7a84d 100644 --- a/tests/functional/opt3_xorxor.asm +++ b/tests/functional/opt3_xorxor.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _push: DEFB 00 _suck: DEFB 00 _paso: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__looproom: xor a ld (_push), a @@ -33,9 +33,9 @@ __LABEL__looproom: ld a, 4 ld (_paso), a jp __LABEL__looproom -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt4_053opt.asm b/tests/functional/opt4_053opt.asm index 49b6fc61f..bc14c2da9 100644 --- a/tests/functional/opt4_053opt.asm +++ b/tests/functional/opt4_053opt.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _subeEgg: DEFB 00 _sail: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_sail) dec a jp nz, __LABEL__enddispara @@ -37,22 +37,22 @@ __MAIN_PROGRAM__: ld a, (40044) ld hl, (40011) sub h - call __ABS8 + call core.__ABS8 ld h, 16 - call __LTI8 + call core.__LTI8 or a jp z, __LABEL__enddispara ld a, (40011) ld hl, (40042) sub h - call __ABS8 + call core.__ABS8 ld h, 20 - call __LTI8 + call core.__LTI8 __LABEL__enddispara: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -65,16 +65,19 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/abs8.asm" ; Returns absolute value for 8 bit signed integer ; + push namespace core __ABS8: - or a - ret p - neg - ret + or a + ret p + neg + ret + pop namespace #line 40 "opt4_053opt.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -92,6 +95,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 41 "opt4_053opt.bas" END diff --git a/tests/functional/opt4_atohl_a.asm b/tests/functional/opt4_atohl_a.asm index 090fd78e2..1b219c147 100644 --- a/tests/functional/opt4_atohl_a.asm +++ b/tests/functional/opt4_atohl_a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _dw1: DEFB 00, 00 _i: DEFB 00, 00 _g: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_g) push af ld a, (_i) push af call _putTile10x8Box__leave ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt4_block_regs.asm b/tests/functional/opt4_block_regs.asm index 4c12cf59e..e27e171e7 100644 --- a/tests/functional/opt4_block_regs.asm +++ b/tests/functional/opt4_block_regs.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_x) ld de, 25 add hl, de @@ -34,9 +34,9 @@ __MAIN_PROGRAM__: ld (hl), a __LABEL1: ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt4_due_0.asm b/tests/functional/opt4_due_0.asm index 4ce804520..58c9641b5 100644 --- a/tests/functional/opt4_due_0.asm +++ b/tests/functional/opt4_due_0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _k: DEFB 05h _n: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_k) xor 31 ld (_k), a @@ -37,9 +37,9 @@ __MAIN_PROGRAM__: or h ld (_k), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt4_inca.asm b/tests/functional/opt4_inca.asm index 451e53adc..5ffe7df35 100644 --- a/tests/functional/opt4_inca.asm +++ b/tests/functional/opt4_inca.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _d1: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 31 add a, 4 ld (_d1), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt4_inout.asm b/tests/functional/opt4_inout.asm index 2b99773c4..f718f5717 100644 --- a/tests/functional/opt4_inout.asm +++ b/tests/functional/opt4_inout.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld bc, 32768 out (c), a @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: ld (_a), a ld (0), a ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/opt4_keepix.asm b/tests/functional/opt4_keepix.asm index ca98c5b66..c1a566646 100644 --- a/tests/functional/opt4_keepix.asm +++ b/tests/functional/opt4_keepix.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld bc, 0 -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,30 +42,30 @@ _test: push hl push hl inc sp - call RND + call core.RND push bc push de push af ld a, 083h ld de, 00020h ld bc, 00000h - call __MULF + call core.__MULF ld hl, -5 - call __PSTOREF + call core.__PSTOREF push ix pop hl ld de, -5 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af ld a, 081h ld de, 00000h ld bc, 00000h - call __ADDF + call core.__ADDF ld hl, -5 - call __PSTOREF + call core.__PSTOREF _test__leave: ld sp, ix pop ix @@ -76,12 +76,13 @@ _test__leave: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -96,19 +97,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -118,13 +120,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 53 "opt4_keepix.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- @@ -135,13 +139,15 @@ __ADDF: ; Addition ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 54 "opt4_keepix.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -153,6 +159,7 @@ __MULF: ; Multiplication ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -163,22 +170,25 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 55 "opt4_keepix.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stores FP number in A ED CB at location HL+IX @@ -186,44 +196,49 @@ __PLOADF: ; IX = Stack Frame ; A ED CB = FP Number #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stored a float number in A ED CB into the address pointed by IX + HL + push namespace core __PSTOREF: - push de + push de ex de, hl ; DE <- HL push ix - pop hl ; HL <- IX + pop hl ; HL <- IX add hl, de ; HL <- IX + DE - pop de + pop de jp __STOREF + pop namespace #line 56 "opt4_keepix.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/random.asm" ; RANDOM functions + push namespace core RANDOMIZE: ; Randomize with 32 bit seed in DE HL ; if SEED = 0, calls ROM to take frames as seed @@ -320,5 +335,6 @@ RND_LOOP: ld a, l ; exponent in A ret ENDP + pop namespace #line 57 "opt4_keepix.bas" END diff --git a/tests/functional/optconst.asm b/tests/functional/optconst.asm index 454ad109e..691c72061 100644 --- a/tests/functional/optconst.asm +++ b/tests/functional/optconst.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld ((__LABEL__label1) + (1)), a xor a @@ -44,9 +44,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,14 +57,14 @@ __END_PROGRAM: ret ld hl, (_a) ld de, (_a + 2) - call __PRINTU32 - call PRINT_EOL + call core.__PRINTU32 + call core.PRINT_EOL __LABEL__label1: __LABEL__label2: ld hl, 0 ld b, h ld c, l - jp __END_PROGRAM + jp core.__END_PROGRAM ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -73,70 +73,75 @@ __LABEL__label2: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -166,49 +171,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -216,319 +227,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -583,614 +614,625 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 45 "optconst.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 46 "optconst.bas" END diff --git a/tests/functional/optspeed.asm b/tests/functional/optspeed.asm index 678e9df46..3ba5fb72a 100644 --- a/tests/functional/optspeed.asm +++ b/tests/functional/optspeed.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _face: DEFB 00 _modoi: DEFB 00 _ds1: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__finish: call _choque ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -83,14 +83,14 @@ __LABEL0: pop hl ld de, -6 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af ld a, 000h ld de, 00000h ld bc, 00000h - call __LEF + call core.__LEF or a jp z, __LABEL10 ld a, 2 @@ -318,14 +318,14 @@ __LABEL60: pop hl ld de, -6 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af ld a, 000h ld de, 00000h ld bc, 00000h - call __LEF + call core.__LEF or a jp z, __LABEL74 ld a, 2 @@ -346,14 +346,14 @@ __LABEL72: pop hl ld de, -6 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af ld a, 000h ld de, 00000h ld bc, 00000h - call __LEF + call core.__LEF or a jp z, __LABEL78 ld a, 2 @@ -387,146 +387,151 @@ _choque__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/lef.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lef.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -543,22 +548,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/lef.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -573,19 +580,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/lef.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -595,15 +603,17 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __LEF: ; A <= B - call __FPSTACK_PUSH2 ; B, A - ; ------------- ROM NO-L-EQL - ld b, 0Ah ; B => A - rst 28h - defb 0Ah ; B => A - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; B, A + ; ------------- ROM NO-L-EQL + ld b, 0Ah ; B => A + rst 28h + defb 0Ah ; B => A + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 360 "optspeed.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -615,6 +625,7 @@ __LEF: ; A <= B ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -625,21 +636,24 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 361 "optspeed.bas" END diff --git a/tests/functional/or16.asm b/tests/functional/or16.asm index 4fd25e162..1919d7704 100644 --- a/tests/functional/or16.asm +++ b/tests/functional/or16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld a, h or l @@ -48,9 +48,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/or32.asm b/tests/functional/or32.asm index 6422bdad1..ef5bcc4db 100644 --- a/tests/functional/or32.asm +++ b/tests/functional/or32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 0 - call __OR32 + call core.__OR32 ld (_b), a ld hl, (_a + 2) push hl @@ -38,7 +38,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __OR32 + call core.__OR32 ld (_b), a ld hl, (_a) ld de, (_a + 2) @@ -46,7 +46,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __OR32 + call core.__OR32 ld (_b), a ld hl, (_a) ld de, (_a + 2) @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __OR32 + call core.__OR32 ld (_b), a ld hl, (_a + 2) push hl @@ -62,14 +62,14 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __OR32 + call core.__OR32 ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,9 +80,10 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/or32.asm" + push namespace core __OR32: ; Performs logical operation A AND B - ; between DEHL and TOP of the stack. - ; Returns A = 0 (False) or A = FF (True) + ; between DEHL and TOP of the stack. + ; Returns A = 0 (False) or A = FF (True) ld a, h or l or d @@ -94,7 +95,8 @@ __OR32: ; Performs logical operation A AND B or e or h or l -#line 24 "/zxbasic/src/arch/zx48k/library-asm/or32.asm" +#line 26 "/zxbasic/src/arch/zx48k/library-asm/or32.asm" ret + pop namespace #line 57 "or32.bas" END diff --git a/tests/functional/or8.asm b/tests/functional/or8.asm index aac5f45ba..1ab86261a 100644 --- a/tests/functional/or8.asm +++ b/tests/functional/or8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -41,9 +41,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/out0.asm b/tests/functional/out0.asm index 23d9e060b..99ef810b2 100644 --- a/tests/functional/out0.asm +++ b/tests/functional/out0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld bc, 254 out (c), a ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l ld bc, 254 out (c), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,77 +49,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -136,10 +139,11 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 27 "out0.bas" END diff --git a/tests/functional/param0.asm b/tests/functional/param0.asm index 032ce94a0..8bffda142 100644 --- a/tests/functional/param0.asm +++ b/tests/functional/param0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _test ld a, 1 - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,13 +56,13 @@ _test: push hl ld de, __LABEL1 pop hl - call __ADDSTR + call core.__ADDSTR _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -203,9 +203,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -213,37 +214,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -253,94 +255,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 55 "param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -406,6 +410,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -435,6 +440,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -447,125 +453,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 56 "param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -574,109 +584,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -684,319 +703,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1051,572 +1090,581 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 57 "param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 58 "param0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 59 "param0.bas" END diff --git a/tests/functional/param1.asm b/tests/functional/param1.asm index 958c4beaf..147dd771e 100644 --- a/tests/functional/param1.asm +++ b/tests/functional/param1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, _a push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,8 @@ _test: ld h, (hl) ld l, c xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _test__leave: ld sp, ix pop ix @@ -83,70 +83,75 @@ __LABEL0: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -176,49 +181,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -226,319 +237,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -593,426 +624,431 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 47 "param1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1139,9 +1175,10 @@ PRINT_EOL_ATTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1149,37 +1186,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1189,135 +1227,139 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 48 "param1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -1462,90 +1504,92 @@ __PRINT_STR: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -1567,132 +1611,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1717,5 +1766,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 49 "param1.bas" END diff --git a/tests/functional/param2.asm b/tests/functional/param2.asm index bb09757fc..56fb0627a 100644 --- a/tests/functional/param2.asm +++ b/tests/functional/param2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _test ld a, 1 - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,13 +56,13 @@ _test: push hl ld de, __LABEL1 pop hl - call __ADDSTR + call core.__ADDSTR _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -203,9 +203,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -213,37 +214,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -253,94 +255,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 55 "param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -406,6 +410,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -435,6 +440,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -447,125 +453,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 56 "param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -574,109 +584,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -684,319 +703,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1051,572 +1090,581 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 57 "param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 58 "param2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 59 "param2.bas" END diff --git a/tests/functional/param_byref_warn.asm b/tests/functional/param_byref_warn.asm index 06349102b..39f6cc6aa 100644 --- a/tests/functional/param_byref_warn.asm +++ b/tests/functional/param_byref_warn.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _b - call __STORE_STR + call core.__STORE_STR ld hl, _b push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,7 +53,7 @@ _test: add ix, sp ld de, __LABEL1 ld bc, 4 - call __PISTORE_STR + call core.__PISTORE_STR _test__leave: ld sp, ix pop ix @@ -147,6 +147,7 @@ __LABEL1: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -176,6 +177,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -301,9 +303,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -311,37 +314,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -354,90 +358,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -507,94 +513,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -616,132 +624,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -766,5 +779,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 47 "param_byref_warn.bas" END diff --git a/tests/functional/parambyref1.asm b/tests/functional/parambyref1.asm index 1b8ee3d3e..a109cccf9 100644 --- a/tests/functional/parambyref1.asm +++ b/tests/functional/parambyref1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 1234 push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -48,8 +48,8 @@ _test2: inc hl ld h, (hl) ld l, c - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL _test2__leave: ld sp, ix pop ix @@ -84,70 +84,75 @@ _test__leave: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -177,49 +182,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -227,319 +238,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -594,469 +625,477 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 58 "parambyref1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1079,76 +1118,79 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 59 "parambyref1.bas" END diff --git a/tests/functional/paramint3.asm b/tests/functional/paramint3.asm index d4d8e365e..9e454d131 100644 --- a/tests/functional/paramint3.asm +++ b/tests/functional/paramint3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) push hl call _p ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/paramnameclash0.asm b/tests/functional/paramnameclash0.asm index d165d4523..2fee44d25 100644 --- a/tests/functional/paramnameclash0.asm +++ b/tests/functional/paramnameclash0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL0 _a.__DATA__.__PTR__: @@ -32,17 +32,17 @@ _a.__DATA__: __LABEL0: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 1 push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/params_implicit.asm b/tests/functional/params_implicit.asm index b6cff39be..53678942b 100644 --- a/tests/functional/params_implicit.asm +++ b/tests/functional/params_implicit.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,7 +42,7 @@ _x: ld de, 00020h ld bc, 00000h ld hl, 4 - call __PSTOREF + call core.__PSTOREF _x__leave: ld sp, ix pop ix @@ -60,40 +60,44 @@ _x__leave: ; IX = Stack Frame ; A ED CB = FP Number #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stored a float number in A ED CB into the address pointed by IX + HL + push namespace core __PSTOREF: - push de + push de ex de, hl ; DE <- HL push ix - pop hl ; HL <- IX + pop hl ; HL <- IX add hl, de ; HL <- IX + DE - pop de + pop de jp __STOREF + pop namespace #line 36 "params_implicit.bas" END diff --git a/tests/functional/paramstr3.asm b/tests/functional/paramstr3.asm index d636c0863..90af7a362 100644 --- a/tests/functional/paramstr3.asm +++ b/tests/functional/paramstr3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) - call __LOADSTR + call core.__LOADSTR push hl call _p ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -54,7 +54,7 @@ _p__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -189,9 +189,10 @@ _p__leave: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -199,37 +200,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -239,94 +241,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 40 "paramstr3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -392,6 +396,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -421,6 +426,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -433,124 +439,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 41 "paramstr3.bas" END diff --git a/tests/functional/paramstr4.asm b/tests/functional/paramstr4.asm index 6e3ef8c09..1e98facea 100644 --- a/tests/functional/paramstr4.asm +++ b/tests/functional/paramstr4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) - call __LOADSTR + call core.__LOADSTR push hl call _p ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _p: add ix, sp ld l, (ix+4) ld h, (ix+5) - call __LOADSTR + call core.__LOADSTR push hl call _r _p__leave: @@ -59,7 +59,7 @@ _p__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -78,7 +78,7 @@ _r__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -213,9 +213,10 @@ _r__leave: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -223,37 +224,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -263,94 +265,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 64 "paramstr4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -416,6 +420,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -445,6 +450,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -457,124 +463,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 65 "paramstr4.bas" END diff --git a/tests/functional/paramstr5.asm b/tests/functional/paramstr5.asm index 686ba307c..0608cc12d 100644 --- a/tests/functional/paramstr5.asm +++ b/tests/functional/paramstr5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) - call __LOADSTR + call core.__LOADSTR push hl call _p ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _p: add ix, sp ld l, (ix+4) ld h, (ix+5) - call __LOADSTR + call core.__LOADSTR push hl call _p_r _p__leave: @@ -59,7 +59,7 @@ _p__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -78,7 +78,7 @@ _p_r__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -213,9 +213,10 @@ _p_r__leave: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -223,37 +224,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -263,94 +265,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 64 "paramstr5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -416,6 +420,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -445,6 +450,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -457,124 +463,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 65 "paramstr5.bas" END diff --git a/tests/functional/pararray0.asm b/tests/functional/pararray0.asm index 4e5d4546a..6652a51ae 100644 --- a/tests/functional/pararray0.asm +++ b/tests/functional/pararray0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _q: DEFW __LABEL0 _q.__DATA__.__PTR__: @@ -48,17 +48,17 @@ _q.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _q push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -77,7 +77,7 @@ _test: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld de, 7 ld (hl), e inc hl @@ -108,81 +108,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -190,16 +193,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -218,6 +221,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 43 "pararray0.bas" END diff --git a/tests/functional/pararray1.asm b/tests/functional/pararray1.asm index 392643ab6..6beeab640 100644 --- a/tests/functional/pararray1.asm +++ b/tests/functional/pararray1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _q: DEFW __LABEL1 _q.__DATA__.__PTR__: @@ -48,17 +48,17 @@ _q.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _q push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -90,7 +90,7 @@ _test: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld de, 7 ld (hl), e inc hl @@ -121,81 +121,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -203,16 +206,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -231,7 +234,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 56 "pararray1.bas" __LABEL0: DEFB 03h diff --git a/tests/functional/pararray10.asm b/tests/functional/pararray10.asm index 542272002..13bedc470 100644 --- a/tests/functional/pararray10.asm +++ b/tests/functional/pararray10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00 _c: @@ -38,8 +38,8 @@ _a.__DATA__: __LABEL5: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld (_i), hl jp __LABEL0 @@ -64,9 +64,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -86,7 +86,7 @@ _func1: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld e, (hl) inc hl ld d, (hl) @@ -138,81 +138,84 @@ _func2__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -220,16 +223,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -248,6 +251,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 83 "pararray10.bas" END diff --git a/tests/functional/pararray11.asm b/tests/functional/pararray11.asm index 41aba48a5..a207f493f 100644 --- a/tests/functional/pararray11.asm +++ b/tests/functional/pararray11.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _func3 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ _func1: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld e, (hl) inc hl ld d, (hl) @@ -103,7 +103,7 @@ _func3: ld hl, -8 ld de, __LABEL5 ld bc, 8 - call __ALLOC_INITIALIZED_LOCAL_ARRAY + call core.__ALLOC_INITIALIZED_LOCAL_ARRAY ld (ix-2), 0 ld (ix-1), 0 jp __LABEL0 @@ -140,7 +140,7 @@ _func3__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -164,81 +164,84 @@ _func3__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -246,16 +249,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -274,7 +277,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 124 "pararray11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" @@ -351,6 +355,7 @@ TMP_ARR_PTR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -380,6 +385,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -445,9 +451,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -455,37 +462,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -498,90 +506,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -595,25 +605,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -628,6 +640,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -677,7 +690,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ldir pop hl ; HL = addr of LBound area if used ret -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 125 "pararray11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -747,94 +761,96 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 126 "pararray11.bas" __LABEL5: DEFB 00h diff --git a/tests/functional/pararray5.asm b/tests/functional/pararray5.asm index b0036bc04..77d517b66 100644 --- a/tests/functional/pararray5.asm +++ b/tests/functional/pararray5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _q: DEFW __LABEL1 _q.__DATA__.__PTR__: @@ -48,17 +48,17 @@ _q.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _q push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -90,7 +90,7 @@ _test: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld de, 7 ld (hl), e inc hl @@ -121,81 +121,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -203,16 +206,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -231,7 +234,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 56 "pararray5.bas" __LABEL0: DEFB 03h diff --git a/tests/functional/pararray6.asm b/tests/functional/pararray6.asm index 6f0bcb89c..7b58bd93e 100644 --- a/tests/functional/pararray6.asm +++ b/tests/functional/pararray6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _q: DEFW __LABEL1 _q.__DATA__.__PTR__: @@ -48,8 +48,8 @@ _q.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _q push hl ld a, 2 @@ -58,9 +58,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -92,7 +92,7 @@ _test: pop hl ld de, 6 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld de, 7 ld (hl), e inc hl @@ -124,81 +124,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -206,16 +209,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -234,7 +237,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 59 "pararray6.bas" __LABEL0: DEFB 03h diff --git a/tests/functional/pararray7.asm b/tests/functional/pararray7.asm index 80d274525..ab9082308 100644 --- a/tests/functional/pararray7.asm +++ b/tests/functional/pararray7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _z: DEFW __LABEL1 _z.__DATA__.__PTR__: @@ -87,8 +87,8 @@ _q.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _q push hl ld hl, _z @@ -97,9 +97,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -131,7 +131,7 @@ _test: pop hl ld de, 6 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld de, 7 ld (hl), e inc hl @@ -146,7 +146,7 @@ _test: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld (hl), 8 _test__leave: ld sp, ix @@ -175,81 +175,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -257,16 +260,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -285,7 +288,8 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 71 "pararray7.bas" __LABEL0: DEFB 03h diff --git a/tests/functional/pararray8.asm b/tests/functional/pararray8.asm index bc09dc4b0..3ac05f8f3 100644 --- a/tests/functional/pararray8.asm +++ b/tests/functional/pararray8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _maximum: DEFB 00 _a: @@ -34,8 +34,8 @@ _a.__DATA__: __LABEL7: DEFW 0000h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _max @@ -43,9 +43,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -66,7 +66,7 @@ _max: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld a, (hl) ld (ix-1), a ld (ix-2), 1 @@ -82,7 +82,7 @@ __LABEL3: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR pop af cp (hl) jp nc, __LABEL6 @@ -94,7 +94,7 @@ __LABEL3: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld a, (hl) ld (ix-1), a __LABEL6: @@ -135,81 +135,84 @@ _max__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -217,16 +220,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -245,6 +248,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 84 "pararray8.bas" END diff --git a/tests/functional/pararray9.asm b/tests/functional/pararray9.asm index 624a2f1f4..552e0db57 100644 --- a/tests/functional/pararray9.asm +++ b/tests/functional/pararray9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _q: DEFW __LABEL0 _q.__DATA__.__PTR__: @@ -48,17 +48,17 @@ _q.__DATA__: __LABEL0: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _q push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -77,7 +77,7 @@ _test: pop hl ld de, 4 add hl, de - call __ARRAY_PTR + call core.__ARRAY_PTR ld de, 7 ld (hl), e inc hl @@ -108,81 +108,84 @@ _test__leave: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -190,16 +193,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -218,6 +221,7 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 43 "pararray9.bas" END diff --git a/tests/functional/plot.asm b/tests/functional/plot.asm index b8ee5aea1..8bf7cf160 100644 --- a/tests/functional/plot.asm +++ b/tests/functional/plot.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,60 +8,60 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 11 push af ld a, 22 - call PLOT + call core.PLOT ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, 22 - call PLOT + call core.PLOT ld a, 11 push af ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l - call PLOT + call core.PLOT ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l push af ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) - call __FTOU32REG + call core.__FTOU32REG ld a, l - call PLOT + call core.PLOT ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -73,77 +73,80 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -160,11 +163,12 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 49 "plot.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" ; MIXED __FASTCAL__ / __CALLE__ PLOT Function @@ -174,6 +178,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -203,97 +208,105 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -301,7 +314,9 @@ __CLS_SCR: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -356,29 +371,31 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + push namespace core PLOT: - PROC - LOCAL PLOT_SUB - LOCAL PIXEL_ADDR - LOCAL COORDS - LOCAL __PLOT_ERR + PROC + LOCAL PLOT_SUB + LOCAL PIXEL_ADDR + LOCAL COORDS + LOCAL __PLOT_ERR LOCAL P_FLAG LOCAL __PLOT_OVER1 P_FLAG EQU 23697 - pop hl - ex (sp), hl ; Callee - ld b, a - ld c, h -#line 35 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 41 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" - ld a, 191 - cp b - jr c, __PLOT_ERR ; jr is faster here (#1) + pop hl + ex (sp), hl ; Callee + ld b, a + ld c, h +#line 37 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 43 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + ld a, 191 + cp b + jr c, __PLOT_ERR ; jr is faster here (#1) __PLOT: ; __FASTCALL__ entry (b, c) = pixel coords (y, x) - ld (COORDS), bc ; Saves current point - ld a, 191 ; Max y coord - call PIXEL_ADDR + ld (COORDS), bc ; Saves current point + ld a, 191 ; Max y coord + call PIXEL_ADDR res 6, h ; Starts from 0 ld bc, (SCREEN_ADDR) add hl, bc ; Now current offset @@ -410,6 +427,7 @@ __PLOT_ERR: PLOT_SUB EQU 22ECh PIXEL_ADDR EQU 22ACh COORDS EQU 5C7Dh - ENDP + ENDP + pop namespace #line 50 "plot.bas" END diff --git a/tests/functional/poke0.asm b/tests/functional/poke0.asm index ce5bab67e..546c96538 100644 --- a/tests/functional/poke0.asm +++ b/tests/functional/poke0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00h DEFB 40h _j: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_j), a jp __LABEL0 @@ -47,9 +47,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/poke1.asm b/tests/functional/poke1.asm index afcdf3214..5162c1829 100644 --- a/tests/functional/poke1.asm +++ b/tests/functional/poke1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/poke2.asm b/tests/functional/poke2.asm index ce5bab67e..546c96538 100644 --- a/tests/functional/poke2.asm +++ b/tests/functional/poke2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,23 +8,23 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00h DEFB 40h _j: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a ld (_j), a jp __LABEL0 @@ -47,9 +47,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/poke7.asm b/tests/functional/poke7.asm index d48689577..ab6ebb60d 100644 --- a/tests/functional/poke7.asm +++ b/tests/functional/poke7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _x: DEFB 00, 00, 00, 00 _y: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) inc hl push hl ld bc, (_x) ld de, (_x + 2) pop hl - call __STORE32 + call core.__STORE32 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,25 +47,27 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" + push namespace core __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 24 "poke7.bas" END diff --git a/tests/functional/pokeref.asm b/tests/functional/pokeref.asm index 945b0ec5a..281ccaea7 100644 --- a/tests/functional/pokeref.asm +++ b/tests/functional/pokeref.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld (0), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/pokeref1.asm b/tests/functional/pokeref1.asm index 537d59d4d..526f63944 100644 --- a/tests/functional/pokeref1.asm +++ b/tests/functional/pokeref1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/pokeref2.asm b/tests/functional/pokeref2.asm index febaf4458..fb501004e 100644 --- a/tests/functional/pokeref2.asm +++ b/tests/functional/pokeref2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__printAt42Coords: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/pooky0.asm b/tests/functional/pooky0.asm index 12d140fc0..c4f3f407d 100644 --- a/tests/functional/pooky0.asm +++ b/tests/functional/pooky0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,7 +57,7 @@ _PintarVidas: pop hl ld de, -15 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af @@ -65,15 +65,15 @@ _PintarVidas: pop hl ld de, -20 add hl, de - call __PLOADF - call __SUBF + call core.__PLOADF + call core.__SUBF push bc push de push af ld a, 081h ld de, 00000h ld bc, 00000h - call __SUBF + call core.__SUBF push bc push de push af @@ -81,7 +81,7 @@ _PintarVidas: pop hl ld de, -5 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af @@ -89,22 +89,22 @@ _PintarVidas: pop hl ld de, -10 add hl, de - call __PLOADF + call core.__PLOADF push bc push de push af ld a, 084h ld de, 00010h ld bc, 00000h - call __MULF - call __ADDF + call core.__MULF + call core.__ADDF push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __ADDF + call core.__ADDF push bc push de push af @@ -144,7 +144,7 @@ _PintarNave: sbc a, a ld e, a ld d, a - call __I32TOFREG + call core.__I32TOFREG _PintarNave__leave: exx ld hl, 30 @@ -163,12 +163,13 @@ __EXIT_FUNCTION: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -183,19 +184,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/addf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -205,13 +207,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __ADDF: ; Addition - call __FPSTACK_PUSH2 - ; ------------- ROM ADD - rst 28h - defb 0fh ; ADD - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 140 "pooky0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- @@ -222,13 +226,15 @@ __ADDF: ; Addition ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 141 "pooky0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -240,6 +246,7 @@ __MULF: ; Multiplication ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -250,22 +257,25 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 142 "pooky0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" ; ------------------------------------------------------------- @@ -276,106 +286,112 @@ __PLOADF: ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __SUBF: ; Subtraction - call __FPSTACK_PUSH2 ; ENTERS B, A - ; ------------- ROM SUB - rst 28h - defb 01h ; EXCHANGE - defb 03h ; SUB - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; ENTERS B, A + ; ------------- ROM SUB + rst 28h + defb 01h ; EXCHANGE + defb 03h ; SUB + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 143 "pooky0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 144 "pooky0.bas" END diff --git a/tests/functional/print.asm b/tests/functional/print.asm index 63482eb12..c6778135c 100644 --- a/tests/functional/print.asm +++ b/tests/functional/print.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,63 +8,63 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 3 - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld a, 3 - call __PRINTI8 - call PRINT_EOL + call core.__PRINTI8 + call core.PRINT_EOL ld hl, 3 - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL ld hl, 3 - call __PRINTI16 - call PRINT_EOL + call core.__PRINTI16 + call core.PRINT_EOL ld de, 3 ld hl, 0 - call __PRINTF16 - call PRINT_EOL + call core.__PRINTF16 + call core.PRINT_EOL ld a, 082h ld de, 00040h ld bc, 00000h - call __PRINTF - call PRINT_EOL + call core.__PRINTF + call core.PRINT_EOL ld hl, __LABEL0 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld de, (_a) ld hl, __LABEL0 - call __ADDSTR + call core.__ADDSTR ld a, 1 - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -84,70 +84,75 @@ __LABEL0: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -177,49 +182,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -227,319 +238,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -594,429 +625,434 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 51 "print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves ; 3 bytes + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 52 "print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1144,9 +1180,10 @@ PRINT_EOL_ATTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1154,37 +1191,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1194,146 +1232,151 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -1348,70 +1391,75 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 53 "print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" @@ -1419,23 +1467,26 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1458,235 +1509,246 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" + push namespace core __PRINTF16: ; Prints a 32bit 16.16 fixed point number - PROC - LOCAL __PRINT_FIX_LOOP - LOCAL __PRINTF16_2 - bit 7, d - jr z, __PRINTF16_2 - call __NEG32 - call __PRINT_MINUS + PROC + LOCAL __PRINT_FIX_LOOP + LOCAL __PRINTF16_2 + bit 7, d + jr z, __PRINTF16_2 + call __NEG32 + call __PRINT_MINUS __PRINTF16_2: - push hl - ex de, hl - call __PRINTU16 ; Prints integer part - pop hl - ld a, h - or l - ret z ; Returns if integer - push hl - ld a, '.' - call __PRINT_DIGIT ; Prints decimal point - pop hl + push hl + ex de, hl + call __PRINTU16 ; Prints integer part + pop hl + ld a, h + or l + ret z ; Returns if integer + push hl + ld a, '.' + call __PRINT_DIGIT ; Prints decimal point + pop hl __PRINT_FIX_LOOP: - ld a, h - or l - ret z ; Returns if no more decimals - xor a - ld d, h - ld e, l - ; Fast NUM * 10 multiplication - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 2) - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 4) - add hl, de ; - adc a, 0 ; AHL = AHL + DE (= X * 5) - add hl, hl - adc a, a ; AHL = AHL * 2 (= X * 10) - push hl - or '0' - call __PRINT_DIGIT - pop hl - jp __PRINT_FIX_LOOP - ENDP + ld a, h + or l + ret z ; Returns if no more decimals + xor a + ld d, h + ld e, l + ; Fast NUM * 10 multiplication + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 2) + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 4) + add hl, de ; + adc a, 0 ; AHL = AHL + DE (= X * 5) + add hl, hl + adc a, a ; AHL = AHL * 2 (= X * 10) + push hl + or '0' + call __PRINT_DIGIT + pop hl + jp __PRINT_FIX_LOOP + ENDP + pop namespace #line 54 "print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 56 "print.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 58 "print.bas" @@ -1764,197 +1826,203 @@ __PRINTU_LOOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 60 "print.bas" END diff --git a/tests/functional/print42.asm b/tests/functional/print42.asm index bb35e5fa5..826a9f758 100644 --- a/tests/functional/print42.asm +++ b/tests/functional/print42.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -499,7 +499,7 @@ _print42__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -634,9 +634,10 @@ _print42__leave: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -644,37 +645,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -684,93 +686,95 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP -#line 487 "print42.bas" + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace +#line 540 "/zxbasic/src/arch/zx48k/library/print42.bas" END diff --git a/tests/functional/print64.asm b/tests/functional/print64.asm index ae3f99a9e..2049ef88c 100644 --- a/tests/functional/print64.asm +++ b/tests/functional/print64.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -300,7 +300,7 @@ _print64__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -435,9 +435,10 @@ _print64__leave: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -445,37 +446,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -485,93 +487,95 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP -#line 288 "print64.bas" + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace +#line 302 "/zxbasic/src/arch/zx48k/library/print64.bas" END diff --git a/tests/functional/print_arrstr.asm b/tests/functional/print_arrstr.asm index c12c2e47e..334911882 100644 --- a/tests/functional/print_arrstr.asm +++ b/tests/functional/print_arrstr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL1 _a.__DATA__.__PTR__: @@ -54,21 +54,22 @@ _a.__DATA__: __LABEL1: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 10 - call __STORE_STR + call core.__STORE_STR ld hl, (_a.__DATA__ + 10) - xor a - call __PRINTSTR - call PRINT_EOL + call core.__LOADSTR + ld a, 1 + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -155,6 +156,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -184,6 +186,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -249,9 +252,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -259,37 +263,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -302,126 +307,130 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret -#line 37 "print_arrstr.bas" + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace +#line 38 "print_arrstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: ; vim:ts=4:sw=4:et: @@ -429,109 +438,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -539,319 +557,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -906,423 +944,426 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP -#line 38 "print_arrstr.bas" + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace +#line 39 "print_arrstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1392,136 +1433,140 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP -#line 39 "print_arrstr.bas" + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace +#line 40 "print_arrstr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 ; Stores value of current string pointed by DE register into address pointed by HL @@ -1614,132 +1659,137 @@ __PRINT_STR: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1764,5 +1814,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret -#line 40 "print_arrstr.bas" + pop namespace +#line 41 "print_arrstr.bas" END diff --git a/tests/functional/print_at.asm b/tests/functional/print_at.asm index 7bcf6d01f..341224f80 100644 --- a/tests/functional/print_at.asm +++ b/tests/functional/print_at.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 10 push af ld a, 10 - call PRINT_AT + call core.PRINT_AT ld hl, __LABEL0 xor a - call __PRINTSTR + call core.__PRINTSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -58,70 +58,75 @@ __LABEL0: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -151,49 +156,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -201,319 +212,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -568,422 +599,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 27 "print_at.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1110,9 +1144,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1120,37 +1155,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1160,134 +1196,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 28 "print_at.bas" END diff --git a/tests/functional/print_comma.asm b/tests/functional/print_comma.asm index 18456fa91..30e91dc03 100644 --- a/tests/functional/print_comma.asm +++ b/tests/functional/print_comma.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 - call __PRINTU8 - call PRINT_COMMA + call core.__PRINTU8 + call core.PRINT_COMMA ld a, 2 - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,70 +49,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -142,49 +147,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -192,319 +203,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -559,537 +590,546 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 23 "print_comma.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 24 "print_comma.bas" END diff --git a/tests/functional/print_eol.asm b/tests/functional/print_eol.asm index c21542054..da4a6960f 100644 --- a/tests/functional/print_eol.asm +++ b/tests/functional/print_eol.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call PRINT_EOL +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,70 +44,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -137,49 +142,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -187,319 +198,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -554,421 +585,424 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 18 "print_eol.bas" END diff --git a/tests/functional/print_eol_attr.asm b/tests/functional/print_eol_attr.asm index f3cc6866a..9771f25ba 100644 --- a/tests/functional/print_eol_attr.asm +++ b/tests/functional/print_eol_attr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,70 +57,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -150,49 +155,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -200,319 +211,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -567,426 +598,431 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 21 "print_eol_attr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1113,9 +1149,10 @@ PRINT_EOL_ATTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1123,37 +1160,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1163,134 +1201,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 22 "print_eol_attr.bas" END diff --git a/tests/functional/print_f.asm b/tests/functional/print_f.asm index 7842a78f8..86d9d0f79 100644 --- a/tests/functional/print_f.asm +++ b/tests/functional/print_f.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld de, (_a + 1) ld bc, (_a + 3) - call __PRINTF + call core.__PRINTF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,70 +56,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -149,49 +154,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -199,319 +210,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -566,422 +597,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1107,9 +1141,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1117,37 +1152,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1157,146 +1193,151 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -1311,46 +1352,49 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 21 "print_f.bas" END diff --git a/tests/functional/print_f16.asm b/tests/functional/print_f16.asm index cf9f3db98..1f4e8997a 100644 --- a/tests/functional/print_f16.asm +++ b/tests/functional/print_f16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) - call __PRINTF16 + call core.__PRINTF16 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,70 +50,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -143,49 +148,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -193,319 +204,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -560,443 +591,448 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" @@ -1004,23 +1040,26 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1043,142 +1082,149 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" + push namespace core __PRINTF16: ; Prints a 32bit 16.16 fixed point number - PROC - LOCAL __PRINT_FIX_LOOP - LOCAL __PRINTF16_2 - bit 7, d - jr z, __PRINTF16_2 - call __NEG32 - call __PRINT_MINUS + PROC + LOCAL __PRINT_FIX_LOOP + LOCAL __PRINTF16_2 + bit 7, d + jr z, __PRINTF16_2 + call __NEG32 + call __PRINT_MINUS __PRINTF16_2: - push hl - ex de, hl - call __PRINTU16 ; Prints integer part - pop hl - ld a, h - or l - ret z ; Returns if integer - push hl - ld a, '.' - call __PRINT_DIGIT ; Prints decimal point - pop hl + push hl + ex de, hl + call __PRINTU16 ; Prints integer part + pop hl + ld a, h + or l + ret z ; Returns if integer + push hl + ld a, '.' + call __PRINT_DIGIT ; Prints decimal point + pop hl __PRINT_FIX_LOOP: - ld a, h - or l - ret z ; Returns if no more decimals - xor a - ld d, h - ld e, l - ; Fast NUM * 10 multiplication - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 2) - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 4) - add hl, de ; - adc a, 0 ; AHL = AHL + DE (= X * 5) - add hl, hl - adc a, a ; AHL = AHL * 2 (= X * 10) - push hl - or '0' - call __PRINT_DIGIT - pop hl - jp __PRINT_FIX_LOOP - ENDP + ld a, h + or l + ret z ; Returns if no more decimals + xor a + ld d, h + ld e, l + ; Fast NUM * 10 multiplication + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 2) + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 4) + add hl, de ; + adc a, 0 ; AHL = AHL + DE (= X * 5) + add hl, hl + adc a, a ; AHL = AHL * 2 (= X * 10) + push hl + or '0' + call __PRINT_DIGIT + pop hl + jp __PRINT_FIX_LOOP + ENDP + pop namespace #line 20 "print_f16.bas" END diff --git a/tests/functional/print_i16.asm b/tests/functional/print_i16.asm index 8c4df11c8..5d981a1e1 100644 --- a/tests/functional/print_i16.asm +++ b/tests/functional/print_i16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) - call __PRINTI16 + call core.__PRINTI16 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,70 +49,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -142,49 +147,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -192,319 +203,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -559,466 +590,474 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1041,75 +1080,78 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 19 "print_i16.bas" END diff --git a/tests/functional/print_i32.asm b/tests/functional/print_i32.asm index 66f0996b0..367758971 100644 --- a/tests/functional/print_i32.asm +++ b/tests/functional/print_i32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) - call __PRINTI32 + call core.__PRINTI32 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,70 +50,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -143,49 +148,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -193,319 +204,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -560,610 +591,621 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 20 "print_i32.bas" END diff --git a/tests/functional/print_i8.asm b/tests/functional/print_i8.asm index 338783c31..0eb4aa53c 100644 --- a/tests/functional/print_i8.asm +++ b/tests/functional/print_i8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) - call __PRINTI8 + call core.__PRINTI8 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,70 +49,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -142,49 +147,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -192,319 +203,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -559,533 +590,542 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 19 "print_i8.bas" END diff --git a/tests/functional/print_tab.asm b/tests/functional/print_tab.asm index 443b5166c..7bc42a30d 100644 --- a/tests/functional/print_tab.asm +++ b/tests/functional/print_tab.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 5 - call PRINT_TAB + call core.PRINT_TAB ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,70 +45,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -138,49 +143,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -188,319 +199,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -555,421 +586,424 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 19 "print_tab.bas" END diff --git a/tests/functional/print_u16.asm b/tests/functional/print_u16.asm index d3c858b86..37599492f 100644 --- a/tests/functional/print_u16.asm +++ b/tests/functional/print_u16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) - call __PRINTU16 + call core.__PRINTU16 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,70 +50,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -143,49 +148,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -193,319 +204,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -560,466 +591,474 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1042,76 +1081,79 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 19 "print_u16.bas" END diff --git a/tests/functional/print_u32.asm b/tests/functional/print_u32.asm index b1c0a926a..700319d37 100644 --- a/tests/functional/print_u32.asm +++ b/tests/functional/print_u32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a + 2) - call __PRINTU32 + call core.__PRINTU32 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,70 +51,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -144,49 +149,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -194,319 +205,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -561,611 +592,622 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 20 "print_u32.bas" END diff --git a/tests/functional/print_u8.asm b/tests/functional/print_u8.asm index 87bb1e9fd..815098cf5 100644 --- a/tests/functional/print_u8.asm +++ b/tests/functional/print_u8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) - call __PRINTU8 + call core.__PRINTU8 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,70 +50,75 @@ __END_PROGRAM: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -143,49 +148,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -193,319 +204,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -560,534 +591,543 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 19 "print_u8.bas" END diff --git a/tests/functional/randomize.asm b/tests/functional/randomize.asm index 891c13015..dd906e99d 100644 --- a/tests/functional/randomize.asm +++ b/tests/functional/randomize.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, 0 ld hl, 0 - call RANDOMIZE + call core.RANDOMIZE ld de, 0 ld hl, 32 - call RANDOMIZE + call core.RANDOMIZE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -43,6 +43,7 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/random.asm" ; RANDOM functions + push namespace core RANDOMIZE: ; Randomize with 32 bit seed in DE HL ; if SEED = 0, calls ROM to take frames as seed @@ -139,5 +140,6 @@ RND_LOOP: ld a, l ; exponent in A ret ENDP + pop namespace #line 23 "randomize.bas" END diff --git a/tests/functional/read.asm b/tests/functional/read.asm index b44002c42..662ba9891 100644 --- a/tests/functional/read.asm +++ b/tests/functional/read.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 9 - call __READ + call core.__READ ld hl, _a - call __STOREF + call core.__STOREF __LABEL__pera: __LABEL__pina: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,7 +51,7 @@ __END_PROGRAM: ret ___DATA__FUNCPTR__0: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR ___DATA__FUNCPTR__0__leave: ret __DATA__0: @@ -137,6 +137,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -166,6 +167,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -231,9 +233,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -241,37 +244,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -284,125 +288,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 48 "read.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -427,23 +435,26 @@ __LOADSTR: ; __FASTCALL__ entry ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -454,91 +465,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -555,124 +570,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -680,18 +701,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -761,94 +783,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -860,6 +884,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1136,32 +1161,35 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 49 "read.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 50 "read.bas" END diff --git a/tests/functional/read10.asm b/tests/functional/read10.asm index 487c12b77..0d6fdc2e8 100644 --- a/tests/functional/read10.asm +++ b/tests/functional/read10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 81h DEFB 40h DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE call _p ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -61,16 +61,16 @@ _p: jp __LABEL0 __LABEL3: ld a, 9 - call __READ + call core.__READ ld hl, -6 - call __PSTOREF + call core.__PSTOREF push ix pop hl ld de, -6 add hl, de - call __PLOADF - call __PRINTF - call PRINT_EOL + call core.__PLOADF + call core.__PRINTF + call core.PRINT_EOL __LABEL4: inc (ix-1) __LABEL0: @@ -95,29 +95,29 @@ ___DATA__FUNCPTR__0: push hl ld h, 085h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call SIN + call core.SIN push bc push de push af ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call TAN + call core.TAN push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __POW - call __MULF + call core.__POW + call core.__MULF ___DATA__FUNCPTR__1__leave: ret ___DATA__FUNCPTR__2: @@ -130,7 +130,7 @@ ___DATA__FUNCPTR__2: push hl ld h, 082h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__2__leave: ret __DATA__0: @@ -150,12 +150,13 @@ __DATA__END: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -170,19 +171,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -192,13 +194,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 115 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" ; Parameter / Local var load @@ -210,6 +214,7 @@ __MULF: ; Multiplication ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -220,22 +225,25 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/ploadf.asm" + push namespace core __PLOADF: push ix pop hl add hl, de jp __LOADF + pop namespace #line 116 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- @@ -250,16 +258,18 @@ __PLOADF: ; 1 st parameter is the BASE (A ED CB) ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core __POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace #line 117 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -268,70 +278,75 @@ __POW: ; Exponentiation ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -361,49 +376,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -411,319 +432,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -778,422 +819,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 118 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1321,9 +1365,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1331,37 +1376,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1371,163 +1417,169 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 119 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stores FP number in A ED CB at location HL+IX @@ -1535,41 +1587,45 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH ; IX = Stack Frame ; A ED CB = FP Number #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stored a float number in A ED CB into the address pointed by IX + HL + push namespace core __PSTOREF: - push de + push de ex de, hl ; DE <- HL push ix - pop hl ; HL <- IX + pop hl ; HL <- IX add hl, de ; HL <- IX + DE - pop de + pop de jp __STOREF + pop namespace #line 120 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -1661,217 +1717,226 @@ __PSTOREF: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1888,124 +1953,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -2013,18 +2084,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -2036,6 +2108,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2312,21 +2385,26 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 121 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 122 "read10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 123 "read10.bas" END diff --git a/tests/functional/read12.asm b/tests/functional/read12.asm index 6c2ee11e2..3fde4a01f 100644 --- a/tests/functional/read12.asm +++ b/tests/functional/read12.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,45 +8,45 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__1 - call __RESTORE + call core.__RESTORE ld a, 2 - call __READ + call core.__READ ld (_a), a - call __PRINTI8 - call PRINT_EOL + call core.__PRINTI8 + call core.PRINT_EOL ld a, 2 - call __READ + call core.__READ ld (_a), a - call __PRINTI8 - call PRINT_EOL + call core.__PRINTI8 + call core.PRINT_EOL __LABEL__test: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,7 +57,7 @@ __END_PROGRAM: ret ___DATA__FUNCPTR__0: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR ___DATA__FUNCPTR__0__leave: ret __DATA__0: @@ -141,6 +141,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -170,6 +171,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -235,9 +237,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -245,37 +248,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -288,125 +292,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 51 "read12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -415,109 +423,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -525,319 +542,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -892,536 +929,545 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 52 "read12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 53 "read12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -1446,23 +1492,26 @@ __PRINTU_LOOP: ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -1473,91 +1522,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1574,124 +1627,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -1699,18 +1758,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -1780,94 +1840,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -1879,6 +1941,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2155,5 +2218,6 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 54 "read12.bas" END diff --git a/tests/functional/read13.asm b/tests/functional/read13.asm index bc6de77f4..37f3122cf 100644 --- a/tests/functional/read13.asm +++ b/tests/functional/read13.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 00h DEFB 80h @@ -55,16 +55,16 @@ _c.__DATA__: __LABEL5: DEFW 0000h DEFB 04h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE xor a ld (_i), a jp __LABEL0 __LABEL3: ld a, 8 - call __READ + call core.__READ push de push hl ld a, (_i) @@ -72,19 +72,19 @@ __LABEL3: ld h, 0 push hl ld hl, _c - call __ARRAY + call core.__ARRAY pop bc pop de - call __STORE32 + call core.__STORE32 ld a, (_i) ld l, a ld h, 0 push hl ld hl, _c - call __ARRAY - call __ILOAD32 - call __PRINTF16 - call PRINT_EOL + call core.__ARRAY + call core.__ILOAD32 + call core.__PRINTF16 + call core.PRINT_EOL __LABEL4: ld hl, _i inc (hl) @@ -97,9 +97,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -115,42 +115,42 @@ ___DATA__FUNCPTR__0: push bc ld bc, 0 push bc - call __MULF16 + call core.__MULF16 ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: ld hl, (_v) ld de, (_v + 2) - call __F16TOFREG - call SIN + call core.__F16TOFREG + call core.SIN push bc push de push af ld hl, (_v) ld de, (_v + 2) - call __F16TOFREG - call TAN + call core.__F16TOFREG + call core.TAN push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __POW - call __MULF + call core.__POW + call core.__MULF ___DATA__FUNCPTR__1__leave: ret ___DATA__FUNCPTR__2: ld hl, (_v) ld de, (_v + 2) - call __F16TOFREG + call core.__F16TOFREG ld hl, 0A2DAh push hl ld hl, 00F49h push hl ld h, 082h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__2__leave: ret __DATA__0: @@ -182,81 +182,84 @@ __DATA__END: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -264,16 +267,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -292,115 +295,121 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 110 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -408,47 +417,51 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 111 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 112 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -463,19 +476,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -485,13 +499,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 113 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" @@ -499,89 +515,93 @@ __MULF: ; Multiplication ; Used with permission. ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') ; 64bit result is returned in H'L'H L B'C'A C + push namespace core __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP - ret ; result in h'l'hlb'c'ac + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/mulf16.asm" + push namespace core __MULF16: ; - ld a, d ; load sgn into a - ex af, af' ; saves it - call __ABS32 ; convert to positive - exx - pop hl ; Return address - pop de ; Low part - ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address - ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) - ex af, af' - xor d ; A register contains resulting sgn - ex af, af' - call __ABS32 ; convert to positive - call __MUL32_64START + ld a, d ; load sgn into a + ex af, af' ; saves it + call __ABS32 ; convert to positive + exx + pop hl ; Return address + pop de ; Low part + ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address + ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) + ex af, af' + xor d ; A register contains resulting sgn + ex af, af' + call __ABS32 ; convert to positive + call __MUL32_64START ; rounding (was not included in zx81) __ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 - ; result returned in dehl - ; input in h'l'hlb'c'ac - sla a ; result bit 47 to carry - exx - ld hl,0 ; ld does not change carry - adc hl,bc ; hl = hl + 0 + carry - push hl - exx - ld bc,0 - adc hl,bc ; hl = hl + 0 + carry - ex de, hl - pop hl ; rounded result in de.hl - ex af, af' ; recovers result sign - or a - jp m, __NEG32 ; if negative, negates it - ret + ; result returned in dehl + ; input in h'l'hlb'c'ac + sla a ; result bit 47 to carry + exx + ld hl,0 ; ld does not change carry + adc hl,bc ; hl = hl + 0 + carry + push hl + exx + ld bc,0 + adc hl,bc ; hl = hl + 0 + carry + ex de, hl + pop hl ; rounded result in de.hl + ex af, af' ; recovers result sign + or a + jp m, __NEG32 ; if negative, negates it + ret + pop namespace #line 114 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- @@ -596,16 +616,18 @@ __ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 ; 1 st parameter is the BASE (A ED CB) ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core __POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace #line 115 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -614,70 +636,75 @@ __POW: ; Exponentiation ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -707,49 +734,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -757,319 +790,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1124,445 +1177,450 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 116 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" @@ -1570,23 +1628,26 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1609,119 +1670,124 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" + push namespace core __PRINTF16: ; Prints a 32bit 16.16 fixed point number - PROC - LOCAL __PRINT_FIX_LOOP - LOCAL __PRINTF16_2 - bit 7, d - jr z, __PRINTF16_2 - call __NEG32 - call __PRINT_MINUS + PROC + LOCAL __PRINT_FIX_LOOP + LOCAL __PRINTF16_2 + bit 7, d + jr z, __PRINTF16_2 + call __NEG32 + call __PRINT_MINUS __PRINTF16_2: - push hl - ex de, hl - call __PRINTU16 ; Prints integer part - pop hl - ld a, h - or l - ret z ; Returns if integer - push hl - ld a, '.' - call __PRINT_DIGIT ; Prints decimal point - pop hl + push hl + ex de, hl + call __PRINTU16 ; Prints integer part + pop hl + ld a, h + or l + ret z ; Returns if integer + push hl + ld a, '.' + call __PRINT_DIGIT ; Prints decimal point + pop hl __PRINT_FIX_LOOP: - ld a, h - or l - ret z ; Returns if no more decimals - xor a - ld d, h - ld e, l - ; Fast NUM * 10 multiplication - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 2) - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 4) - add hl, de ; - adc a, 0 ; AHL = AHL + DE (= X * 5) - add hl, hl - adc a, a ; AHL = AHL * 2 (= X * 10) - push hl - or '0' - call __PRINT_DIGIT - pop hl - jp __PRINT_FIX_LOOP - ENDP + ld a, h + or l + ret z ; Returns if no more decimals + xor a + ld d, h + ld e, l + ; Fast NUM * 10 multiplication + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 2) + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 4) + add hl, de ; + adc a, 0 ; AHL = AHL + DE (= X * 5) + add hl, hl + adc a, a ; AHL = AHL * 2 (= X * 10) + push hl + or '0' + call __PRINT_DIGIT + pop hl + jp __PRINT_FIX_LOOP + ENDP + pop namespace #line 117 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -1866,9 +1932,10 @@ __PRINT_FIX_LOOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1876,37 +1943,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -1919,131 +1987,136 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -2054,67 +2127,69 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -2131,40 +2206,43 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -2234,94 +2312,96 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -2333,6 +2413,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2609,43 +2690,50 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 118 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 119 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/store32.asm" + push namespace core __PISTORE32: - push hl - push ix - pop hl - add hl, bc - pop bc + push hl + push ix + pop hl + add hl, bc + pop bc __ISTORE32: ; Load address at hl, and stores E,D,B,C integer at that address - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __STORE32: ; Stores the given integer in DEBC at address HL - ld (hl), c - inc hl - ld (hl), b - inc hl - ld (hl), e - inc hl - ld (hl), d - ret + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret + pop namespace #line 120 "read13.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 121 "read13.bas" END diff --git a/tests/functional/read14.asm b/tests/functional/read14.asm index 2916b8027..c248f29a1 100644 --- a/tests/functional/read14.asm +++ b/tests/functional/read14.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _j: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 4 - call __READ + call core.__READ ld (_j), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -71,6 +71,7 @@ __DATA__END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -100,6 +101,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -226,9 +228,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -236,37 +239,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -279,148 +283,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -431,91 +442,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -532,124 +547,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -657,18 +678,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -738,94 +760,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -837,6 +861,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1113,5 +1138,6 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 25 "read14.bas" END diff --git a/tests/functional/read4.asm b/tests/functional/read4.asm index a221f799b..f324c68eb 100644 --- a/tests/functional/read4.asm +++ b/tests/functional/read4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 81h DEFB 00h @@ -62,28 +62,28 @@ _x.__DATA__: __LABEL1: DEFW 0000h DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld hl, _v + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 082h ld de, 00040h ld bc, 00000h - call __MULF + call core.__MULF ld hl, _x.__DATA__ + 10 - call __STOREF + call core.__STOREF ld a, 9 - call __READ + call core.__READ ld hl, _x + 10 - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -102,34 +102,34 @@ ___DATA__FUNCPTR__0: push hl ld h, 085h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call SIN + call core.SIN push bc push de push af ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call TAN + call core.TAN push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __POW - call __MULF + call core.__POW + call core.__MULF ___DATA__FUNCPTR__1__leave: ret ___DATA__FUNCPTR__2: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR ___DATA__FUNCPTR__2__leave: ret __DATA__0: @@ -215,6 +215,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -244,6 +245,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -309,9 +311,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -319,37 +322,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -362,137 +366,142 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 89 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -507,19 +516,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -529,13 +539,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 90 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- @@ -550,22 +562,25 @@ __MULF: ; Multiplication ; 1 st parameter is the BASE (A ED CB) ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core __POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace #line 91 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -586,6 +601,7 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 92 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -610,23 +626,26 @@ __FP_PUSH_REV: ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -637,91 +656,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -738,124 +761,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -863,18 +892,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -944,94 +974,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -1043,6 +1075,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1319,48 +1352,55 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 93 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 94 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 95 "read4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 96 "read4.bas" END diff --git a/tests/functional/read5.asm b/tests/functional/read5.asm index 5ec155083..15ce80c8e 100644 --- a/tests/functional/read5.asm +++ b/tests/functional/read5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 81h DEFB 40h @@ -36,32 +36,32 @@ _d: DEFB 00, 00, 00, 00, 00 _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 1 ld (_i), a jp __LABEL0 __LABEL3: ld a, 9 - call __READ + call core.__READ ld hl, _c - call __STOREF + call core.__STOREF ld a, 9 - call __READ + call core.__READ ld hl, _d - call __STOREF + call core.__STOREF ld a, (_c) ld de, (_c + 1) ld bc, (_c + 3) - call __PRINTF - call PRINT_COMMA + call core.__PRINTF + call core.PRINT_COMMA ld a, (_d) ld de, (_d + 1) ld bc, (_d + 3) - call __PRINTF - call PRINT_EOL + call core.__PRINTF + call core.PRINT_EOL __LABEL4: ld hl, _i inc (hl) @@ -74,9 +74,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -95,29 +95,29 @@ ___DATA__FUNCPTR__0: push hl ld h, 085h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call SIN + call core.SIN push bc push de push af ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call TAN + call core.TAN push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __POW - call __MULF + call core.__POW + call core.__MULF ___DATA__FUNCPTR__1__leave: ret ___DATA__FUNCPTR__2: @@ -130,7 +130,7 @@ ___DATA__FUNCPTR__2: push hl ld h, 082h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__2__leave: ret __DATA__0: @@ -150,12 +150,13 @@ __DATA__END: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -170,19 +171,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -192,13 +194,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 109 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- @@ -213,16 +217,18 @@ __MULF: ; Multiplication ; 1 st parameter is the BASE (A ED CB) ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core __POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace #line 110 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -231,70 +237,75 @@ __POW: ; Exponentiation ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -324,49 +335,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -374,319 +391,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -741,422 +778,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 111 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1284,9 +1324,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1294,37 +1335,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1334,163 +1376,169 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 112 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -1582,148 +1630,155 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -1734,91 +1789,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1835,124 +1894,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -1960,18 +2025,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -1983,6 +2049,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2259,48 +2326,55 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 113 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 114 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 115 "read5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 116 "read5.bas" END diff --git a/tests/functional/read8.asm b/tests/functional/read8.asm index 6fea37041..7fe71fc78 100644 --- a/tests/functional/read8.asm +++ b/tests/functional/read8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 81h DEFB 40h @@ -60,23 +60,23 @@ _c.__DATA__: __LABEL5: DEFW 0000h DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 1 ld (_i), a jp __LABEL0 __LABEL3: ld a, 9 - call __READ + call core.__READ ld hl, _c + 5 - call __STOREF + call core.__STOREF ld a, (_c.__DATA__ + 5) ld de, (_c.__DATA__ + 5 + 1) ld bc, (_c.__DATA__ + 5 + 3) - call __PRINTF - call PRINT_EOL + call core.__PRINTF + call core.PRINT_EOL __LABEL4: ld hl, _i inc (hl) @@ -89,9 +89,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -110,29 +110,29 @@ ___DATA__FUNCPTR__0: push hl ld h, 085h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call SIN + call core.SIN push bc push de push af ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call TAN + call core.TAN push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __POW - call __MULF + call core.__POW + call core.__MULF ___DATA__FUNCPTR__1__leave: ret ___DATA__FUNCPTR__2: @@ -145,7 +145,7 @@ ___DATA__FUNCPTR__2: push hl ld h, 082h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__2__leave: ret __DATA__0: @@ -165,12 +165,13 @@ __DATA__END: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -185,19 +186,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -207,13 +209,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 100 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- @@ -228,16 +232,18 @@ __MULF: ; Multiplication ; 1 st parameter is the BASE (A ED CB) ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core __POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace #line 101 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -246,70 +252,75 @@ __POW: ; Exponentiation ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -339,49 +350,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -389,319 +406,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -756,422 +793,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 102 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1299,9 +1339,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1309,37 +1350,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1349,163 +1391,169 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 103 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -1597,148 +1645,155 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -1749,91 +1804,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1850,124 +1909,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -1975,18 +2040,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -1998,6 +2064,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2274,48 +2341,55 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 104 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 105 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 106 "read8.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 107 "read8.bas" END diff --git a/tests/functional/read9.asm b/tests/functional/read9.asm index 9a25ca476..aa631793a 100644 --- a/tests/functional/read9.asm +++ b/tests/functional/read9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _v: DEFB 81h DEFB 40h @@ -60,16 +60,16 @@ _c.__DATA__: __LABEL5: DEFW 0000h DEFB 05h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE xor a ld (_i), a jp __LABEL0 __LABEL3: ld a, 9 - call __READ + call core.__READ push bc push de push af @@ -78,20 +78,20 @@ __LABEL3: ld h, 0 push hl ld hl, _c - call __ARRAY + call core.__ARRAY pop af pop de pop bc - call __STOREF + call core.__STOREF ld a, (_i) ld l, a ld h, 0 push hl ld hl, _c - call __ARRAY - call __LOADF - call __PRINTF - call PRINT_EOL + call core.__ARRAY + call core.__LOADF + call core.__PRINTF + call core.PRINT_EOL __LABEL4: ld hl, _i inc (hl) @@ -104,9 +104,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -125,29 +125,29 @@ ___DATA__FUNCPTR__0: push hl ld h, 085h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__0__leave: ret ___DATA__FUNCPTR__1: ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call SIN + call core.SIN push bc push de push af ld a, (_v) ld de, (_v + 1) ld bc, (_v + 3) - call TAN + call core.TAN push bc push de push af ld a, 082h ld de, 00000h ld bc, 00000h - call __POW - call __MULF + call core.__POW + call core.__MULF ___DATA__FUNCPTR__1__leave: ret ___DATA__FUNCPTR__2: @@ -160,7 +160,7 @@ ___DATA__FUNCPTR__2: push hl ld h, 082h push hl - call __MULF + call core.__MULF ___DATA__FUNCPTR__2__leave: ret __DATA__0: @@ -192,81 +192,84 @@ __DATA__END: ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul16.asm" + push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack - ; Works for both signed and unsigned - PROC - LOCAL __MUL16LOOP - LOCAL __MUL16NOADD - ex de, hl - pop hl ; Return address - ex (sp), hl ; CALLEE caller convention + ; Works for both signed and unsigned + PROC + LOCAL __MUL16LOOP + LOCAL __MUL16NOADD + ex de, hl + pop hl ; Return address + ex (sp), hl ; CALLEE caller convention __MUL16_FAST: - ld b, 16 - ld a, h - ld c, l - ld hl, 0 + ld b, 16 + ld a, h + ld c, l + ld hl, 0 __MUL16LOOP: - add hl, hl ; hl << 1 - sla c - rla ; a,c << 1 - jp nc, __MUL16NOADD - add hl, de + add hl, hl ; hl << 1 + sla c + rla ; a,c << 1 + jp nc, __MUL16NOADD + add hl, de __MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP + djnz __MUL16LOOP + ret ; Result in hl (16 lower bits) + ENDP + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/array.asm" #line 24 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + push namespace core __ARRAY_PTR: ;; computes an array offset from a pointer ld c, (hl) inc hl ld h, (hl) ld l, c __ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL RET_ADDRESS ; Stores return address - LOCAL TMP_ARR_PTR ; Stores pointer temporarily + PROC + LOCAL LOOP + LOCAL ARRAY_END + LOCAL RET_ADDRESS ; Stores return address + LOCAL TMP_ARR_PTR ; Stores pointer temporarily ld e, (hl) inc hl ld d, (hl) inc hl ld (TMP_ARR_PTR), hl ex de, hl - ex (sp), hl ; Return address in HL, array address in the stack - ld (RET_ADDRESS + 1), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Offset "accumulator" + ex (sp), hl ; Return address in HL, array address in the stack + ld (RET_ADDRESS + 1), hl ; Stores it for later + exx + pop hl ; Will use H'L' as the pointer + ld c, (hl) ; Loads Number of dimensions from (hl) + inc hl + ld b, (hl) + inc hl ; Ready + exx + ld hl, 0 ; HL = Offset "accumulator" LOOP: -#line 62 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - pop bc ; Get next index (Ai) from the stack -#line 72 "/zxbasic/src/arch/zx48k/library-asm/array.asm" - add hl, bc ; Adds current index - exx ; Checks if B'C' = 0 - ld a, b ; Which means we must exit (last element is not multiplied by anything) - or c - jr z, ARRAY_END ; if B'Ci == 0 we are done - ld e, (hl) ; Loads next dimension into D'E' - inc hl - ld d, (hl) - inc hl - push de - dec bc ; Decrements loop counter - exx - pop de ; DE = Max bound Number (i-th dimension) +#line 64 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + pop bc ; Get next index (Ai) from the stack +#line 74 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + add hl, bc ; Adds current index + exx ; Checks if B'C' = 0 + ld a, b ; Which means we must exit (last element is not multiplied by anything) + or c + jr z, ARRAY_END ; if B'Ci == 0 we are done + ld e, (hl) ; Loads next dimension into D'E' + inc hl + ld d, (hl) + inc hl + push de + dec bc ; Decrements loop counter + exx + pop de ; DE = Max bound Number (i-th dimension) call __FNMUL - jp LOOP + jp LOOP ARRAY_END: - ld a, (hl) - exx -#line 101 "/zxbasic/src/arch/zx48k/library-asm/array.asm" + ld a, (hl) + exx +#line 103 "/zxbasic/src/arch/zx48k/library-asm/array.asm" LOCAL ARRAY_SIZE_LOOP ex de, hl ld hl, 0 @@ -274,16 +277,16 @@ ARRAY_END: ARRAY_SIZE_LOOP: add hl, de djnz ARRAY_SIZE_LOOP -#line 111 "/zxbasic/src/arch/zx48k/library-asm/array.asm" +#line 113 "/zxbasic/src/arch/zx48k/library-asm/array.asm" ex de, hl - ld hl, (TMP_ARR_PTR) - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - add hl, de ; Adds element start + ld hl, (TMP_ARR_PTR) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + add hl, de ; Adds element start RET_ADDRESS: - jp 0 + jp 0 ;; Performs a faster multiply for little 16bit numbs LOCAL __FNMUL, __FNMUL2 __FNMUL: @@ -302,13 +305,15 @@ __FNMUL2: ret TMP_ARR_PTR: DW 0 ; temporary storage for pointer to tables - ENDP + ENDP + pop namespace #line 115 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -319,28 +324,30 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 116 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -355,19 +362,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mulf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -377,13 +385,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 + ; ------------- ROM MUL + rst 28h + defb 04h ; + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 117 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pow.asm" ; ------------------------------------------------------------- @@ -398,16 +408,18 @@ __MULF: ; Multiplication ; 1 st parameter is the BASE (A ED CB) ; 2 nd parameter (Top of the stack) is Exponent ; ------------------------------------------------------------- + push namespace core __POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace #line 118 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -416,70 +428,75 @@ __POW: ; Exponentiation ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -509,49 +526,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -559,319 +582,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -926,422 +969,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 119 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1469,9 +1515,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1479,37 +1526,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1519,163 +1567,169 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 120 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; This implements READ & RESTORE functions @@ -1767,217 +1821,226 @@ __PRINTF: ; Prints a Fixed point Number stored in C ED LH ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -1994,124 +2057,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -2119,18 +2188,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -2142,6 +2212,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2418,48 +2489,55 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 121 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sin.asm" + push namespace core SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 122 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 123 "read9.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/tan.asm" + push namespace core TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 124 "read9.bas" END diff --git a/tests/functional/readbug.asm b/tests/functional/readbug.asm index fcf1ba1c0..c2e9f965c 100644 --- a/tests/functional/readbug.asm +++ b/tests/functional/readbug.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _r1: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 3 - call __READ + call core.__READ ld (_r1), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -69,6 +69,7 @@ __DATA__END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -98,6 +99,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -224,9 +226,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -234,37 +237,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -277,148 +281,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -429,91 +440,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -530,124 +545,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -655,18 +676,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -736,94 +758,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -835,6 +859,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1111,5 +1136,6 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 23 "readbug.bas" END diff --git a/tests/functional/readokdown.asm b/tests/functional/readokdown.asm index 61ff13a3a..eb33ef2e4 100644 --- a/tests/functional/readokdown.asm +++ b/tests/functional/readokdown.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i8: DEFB 00 _u8: @@ -40,83 +40,83 @@ _f16: DEFB 00, 00, 00, 00 _flt: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 2 - call __READ + call core.__READ ld (_i8), a - call __PRINTI8 - call PRINT_EOL + call core.__PRINTI8 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 3 - call __READ + call core.__READ ld (_u8), a - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 4 - call __READ + call core.__READ ld (_i16), hl - call __PRINTI16 - call PRINT_EOL + call core.__PRINTI16 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 5 - call __READ + call core.__READ ld (_u16), hl - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 6 - call __READ + call core.__READ ld (_i32), hl ld (_i32 + 2), de ld hl, (_i32) ld de, (_i32 + 2) - call __PRINTI32 - call PRINT_EOL + call core.__PRINTI32 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 7 - call __READ + call core.__READ ld (_u32), hl ld (_u32 + 2), de ld hl, (_u32) ld de, (_u32 + 2) - call __PRINTU32 - call PRINT_EOL + call core.__PRINTU32 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 8 - call __READ + call core.__READ ld (_f16), hl ld (_f16 + 2), de ld hl, (_f16) ld de, (_f16 + 2) - call __PRINTF16 - call PRINT_EOL + call core.__PRINTF16 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 9 - call __READ + call core.__READ ld hl, _flt - call __STOREF + call core.__STOREF ld a, (_flt) ld de, (_flt + 1) ld bc, (_flt + 3) - call __PRINTF - call PRINT_EOL + call core.__PRINTF + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -139,70 +139,75 @@ __DATA__END: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -232,49 +237,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -282,319 +293,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -649,422 +680,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 92 "readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1192,9 +1226,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1202,37 +1237,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1242,146 +1278,151 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -1396,70 +1437,75 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 93 "readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" @@ -1467,23 +1513,26 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1506,380 +1555,395 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" + push namespace core __PRINTF16: ; Prints a 32bit 16.16 fixed point number - PROC - LOCAL __PRINT_FIX_LOOP - LOCAL __PRINTF16_2 - bit 7, d - jr z, __PRINTF16_2 - call __NEG32 - call __PRINT_MINUS + PROC + LOCAL __PRINT_FIX_LOOP + LOCAL __PRINTF16_2 + bit 7, d + jr z, __PRINTF16_2 + call __NEG32 + call __PRINT_MINUS __PRINTF16_2: - push hl - ex de, hl - call __PRINTU16 ; Prints integer part - pop hl - ld a, h - or l - ret z ; Returns if integer - push hl - ld a, '.' - call __PRINT_DIGIT ; Prints decimal point - pop hl + push hl + ex de, hl + call __PRINTU16 ; Prints integer part + pop hl + ld a, h + or l + ret z ; Returns if integer + push hl + ld a, '.' + call __PRINT_DIGIT ; Prints decimal point + pop hl __PRINT_FIX_LOOP: - ld a, h - or l - ret z ; Returns if no more decimals - xor a - ld d, h - ld e, l - ; Fast NUM * 10 multiplication - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 2) - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 4) - add hl, de ; - adc a, 0 ; AHL = AHL + DE (= X * 5) - add hl, hl - adc a, a ; AHL = AHL * 2 (= X * 10) - push hl - or '0' - call __PRINT_DIGIT - pop hl - jp __PRINT_FIX_LOOP - ENDP + ld a, h + or l + ret z ; Returns if no more decimals + xor a + ld d, h + ld e, l + ; Fast NUM * 10 multiplication + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 2) + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 4) + add hl, de ; + adc a, 0 ; AHL = AHL + DE (= X * 5) + add hl, hl + adc a, a ; AHL = AHL * 2 (= X * 10) + push hl + or '0' + call __PRINT_DIGIT + pop hl + jp __PRINT_FIX_LOOP + ENDP + pop namespace #line 94 "readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 96 "readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 97 "readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 98 "readokdown.bas" @@ -1977,148 +2041,155 @@ __PRINTU_LOOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -2129,67 +2200,69 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -2206,124 +2279,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -2331,18 +2410,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -2354,6 +2434,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2630,32 +2711,35 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 101 "readokdown.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 102 "readokdown.bas" END diff --git a/tests/functional/readokup.asm b/tests/functional/readokup.asm index 154cae724..1e0547496 100644 --- a/tests/functional/readokup.asm +++ b/tests/functional/readokup.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i8: DEFB 00 _u8: @@ -40,83 +40,83 @@ _f16: DEFB 00, 00, 00, 00 _flt: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 2 - call __READ + call core.__READ ld (_i8), a - call __PRINTI8 - call PRINT_EOL + call core.__PRINTI8 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 3 - call __READ + call core.__READ ld (_u8), a - call __PRINTU8 - call PRINT_EOL + call core.__PRINTU8 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 4 - call __READ + call core.__READ ld (_i16), hl - call __PRINTI16 - call PRINT_EOL + call core.__PRINTI16 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 5 - call __READ + call core.__READ ld (_u16), hl - call __PRINTU16 - call PRINT_EOL + call core.__PRINTU16 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 6 - call __READ + call core.__READ ld (_i32), hl ld (_i32 + 2), de ld hl, (_i32) ld de, (_i32 + 2) - call __PRINTI32 - call PRINT_EOL + call core.__PRINTI32 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 7 - call __READ + call core.__READ ld (_u32), hl ld (_u32 + 2), de ld hl, (_u32) ld de, (_u32 + 2) - call __PRINTU32 - call PRINT_EOL + call core.__PRINTU32 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 8 - call __READ + call core.__READ ld (_f16), hl ld (_f16 + 2), de ld hl, (_f16) ld de, (_f16 + 2) - call __PRINTF16 - call PRINT_EOL + call core.__PRINTF16 + call core.PRINT_EOL ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 9 - call __READ + call core.__READ ld hl, _flt - call __STOREF + call core.__STOREF ld a, (_flt) ld de, (_flt + 1) ld bc, (_flt + 3) - call __PRINTF - call PRINT_EOL + call core.__PRINTF + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -138,70 +138,75 @@ __DATA__END: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -231,49 +236,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -281,319 +292,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs into temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -648,422 +679,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 91 "readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" @@ -1191,9 +1225,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1201,37 +1236,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1241,146 +1277,151 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -1395,70 +1436,75 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf.asm" + push namespace core __PRINTF: ; Prints a Fixed point Number stored in C ED LH - PROC - LOCAL RECLAIM2 - LOCAL STK_END + PROC + LOCAL RECLAIM2 + LOCAL STK_END STK_END EQU 5C65h - ld hl, (ATTR_T) - push hl ; Saves ATTR_T since BUG ROM changes it - ld hl, (STK_END) - push hl ; Stores STK_END - call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - ex de, hl ; String position now in HL - push bc + ld hl, (ATTR_T) + push hl ; Saves ATTR_T since BUG ROM changes it + ld hl, (STK_END) + push hl ; Stores STK_END + call __FPSTACK_PUSH ; Push number into stack + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + ex de, hl ; String position now in HL + push bc xor a ; Avoid the str to be FREED from heap - call __PRINT_STR - pop bc - inc bc - jp RECLAIM2 ; Frees TMP Memory + call __PRINT_STR + pop bc + inc bc + jp RECLAIM2 ; Frees TMP Memory RECLAIM2 EQU 19E8h - ENDP + ENDP + pop namespace #line 92 "readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" @@ -1466,23 +1512,26 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1505,380 +1554,395 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printf16.asm" + push namespace core __PRINTF16: ; Prints a 32bit 16.16 fixed point number - PROC - LOCAL __PRINT_FIX_LOOP - LOCAL __PRINTF16_2 - bit 7, d - jr z, __PRINTF16_2 - call __NEG32 - call __PRINT_MINUS + PROC + LOCAL __PRINT_FIX_LOOP + LOCAL __PRINTF16_2 + bit 7, d + jr z, __PRINTF16_2 + call __NEG32 + call __PRINT_MINUS __PRINTF16_2: - push hl - ex de, hl - call __PRINTU16 ; Prints integer part - pop hl - ld a, h - or l - ret z ; Returns if integer - push hl - ld a, '.' - call __PRINT_DIGIT ; Prints decimal point - pop hl + push hl + ex de, hl + call __PRINTU16 ; Prints integer part + pop hl + ld a, h + or l + ret z ; Returns if integer + push hl + ld a, '.' + call __PRINT_DIGIT ; Prints decimal point + pop hl __PRINT_FIX_LOOP: - ld a, h - or l - ret z ; Returns if no more decimals - xor a - ld d, h - ld e, l - ; Fast NUM * 10 multiplication - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 2) - add hl, hl ; - adc a, a ; AHL = AHL * 2 (= X * 4) - add hl, de ; - adc a, 0 ; AHL = AHL + DE (= X * 5) - add hl, hl - adc a, a ; AHL = AHL * 2 (= X * 10) - push hl - or '0' - call __PRINT_DIGIT - pop hl - jp __PRINT_FIX_LOOP - ENDP + ld a, h + or l + ret z ; Returns if no more decimals + xor a + ld d, h + ld e, l + ; Fast NUM * 10 multiplication + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 2) + add hl, hl ; + adc a, a ; AHL = AHL * 2 (= X * 4) + add hl, de ; + adc a, 0 ; AHL = AHL + DE (= X * 5) + add hl, hl + adc a, a ; AHL = AHL * 2 (= X * 10) + push hl + or '0' + call __PRINT_DIGIT + pop hl + jp __PRINT_FIX_LOOP + ENDP + pop namespace #line 93 "readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 95 "readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 96 "readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 97 "readokup.bas" @@ -1976,148 +2040,155 @@ __PRINTU_LOOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -2128,67 +2199,69 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -2205,124 +2278,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -2330,18 +2409,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -2353,6 +2433,7 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -2629,32 +2710,35 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 100 "readokup.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 101 "readokup.bas" END diff --git a/tests/functional/recur0.asm b/tests/functional/recur0.asm index fade95d1a..6cd045aa9 100644 --- a/tests/functional/recur0.asm +++ b/tests/functional/recur0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/recurse_filter.asm b/tests/functional/recurse_filter.asm index d612cb219..be99c5df6 100644 --- a/tests/functional/recurse_filter.asm +++ b/tests/functional/recurse_filter.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: xor a push af call _test @@ -29,9 +29,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/refconstparam.asm b/tests/functional/refconstparam.asm index a6c15f215..8ec60771d 100644 --- a/tests/functional/refconstparam.asm +++ b/tests/functional/refconstparam.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/refconstparam2.asm b/tests/functional/refconstparam2.asm index a6c15f215..8ec60771d 100644 --- a/tests/functional/refconstparam2.asm +++ b/tests/functional/refconstparam2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/refconstparam4.asm b/tests/functional/refconstparam4.asm index 20b346a5a..14da9cf21 100644 --- a/tests/functional/refconstparam4.asm +++ b/tests/functional/refconstparam4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 4660 ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/refconstparam5.asm b/tests/functional/refconstparam5.asm index 61acabb71..dcc777562 100644 --- a/tests/functional/refconstparam5.asm +++ b/tests/functional/refconstparam5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__b: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/refconstparam6.asm b/tests/functional/refconstparam6.asm index 61acabb71..dcc777562 100644 --- a/tests/functional/refconstparam6.asm +++ b/tests/functional/refconstparam6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__b: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/restore0.asm b/tests/functional/restore0.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/restore0.asm +++ b/tests/functional/restore0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/restore1.asm b/tests/functional/restore1.asm index 38003593b..4817095e1 100644 --- a/tests/functional/restore1.asm +++ b/tests/functional/restore1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__1000: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 9 - call __READ + call core.__READ ld hl, _a - call __STOREF + call core.__STOREF __LABEL__1010: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,6 +76,7 @@ __DATA__END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -105,6 +106,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -231,9 +233,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -241,37 +244,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -284,148 +288,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -436,91 +447,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -537,124 +552,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -662,18 +683,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -743,94 +765,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -842,6 +866,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1118,32 +1143,35 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 30 "restore1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 31 "restore1.bas" END diff --git a/tests/functional/restore2.asm b/tests/functional/restore2.asm index d9b7a65c5..b64e37a55 100644 --- a/tests/functional/restore2.asm +++ b/tests/functional/restore2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/restore3.asm b/tests/functional/restore3.asm index d9e00d465..5d4a2256a 100644 --- a/tests/functional/restore3.asm +++ b/tests/functional/restore3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __DATA__0 - call __RESTORE + call core.__RESTORE ld a, 9 - call __READ + call core.__READ ld hl, _a - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -74,6 +74,7 @@ __DATA__END: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -103,6 +104,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 23 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -229,9 +231,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -239,37 +242,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -282,148 +286,155 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 24 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL ; DE,HL <-- (HL) + push namespace core __ILOAD32: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - ex de, hl - ret + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + ex de, hl + ret + pop namespace #line 25 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL ;A DE, BC <-- ((HL)) + push namespace core __ILOADF: ld a, (hl) inc hl @@ -434,91 +445,95 @@ __ILOADF: ; stored at position pointed by POINTER HL ;A DE, BC <-- (HL) __LOADF: ; Loads a 40 bits FP number from address pointed by HL - ld a, (hl) - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld c, (hl) - inc hl - ld b, (hl) - ret + ld a, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + inc hl + ld c, (hl) + inc hl + ld b, (hl) + ret + pop namespace #line 26 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -535,124 +550,130 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" + push namespace core __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal - ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Input FP number in A EDCB (A exponent, EDCB mantissa) ld l, a ; Saves exponent for later - or d - or e - or b - or c + or d + or e + or b + or c ld h, e - ret z ; Return if ZERO - push hl ; Stores it for later (Contains sign in H, exponent in L) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l + ret z ; Return if ZERO + push hl ; Stores it for later (Contains sign in H, exponent in L) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l pop bc - ld a, c ; Get exponent - sub 112 ; Exponent -= 128 + 16 + ld a, c ; Get exponent + sub 112 ; Exponent -= 128 + 16 push bc ; Saves sign in b again - jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) - jp __FTOU32REG_LOOP ; proceed as an u32 integer + jp z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jp c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 + 16 (we need to shift 16 bit more) + jp __FTOU32REG_LOOP ; proceed as an u32 integer + pop namespace #line 27 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" + push namespace core __F16TOFREG: ; Converts a 16.16 signed fixed point (stored in DEHL) - ; to a Floating Point Number returned in (C ED CB) + ; to a Floating Point Number returned in (C ED CB) PROC LOCAL __F16TOFREG2 - ld a, d - or a ; Test sign - jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __F16TOFREG2 ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ld a, d + or a ; Test sign + jp p, __F16TOFREG2 ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __F16TOFREG2 ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL + ; to a Floating point number returned in C DE HL ld a, d or e or h @@ -660,18 +681,19 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ld b, h ld c, l ret z ; Return 00 0000 0000 if 0 - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 112 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c - jp __U32TOFREG_LOOP ; Proceed as an integer + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 112 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c + jp __U32TOFREG_LOOP ; Proceed as an integer ENDP + pop namespace #line 28 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -741,94 +763,96 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 29 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 31 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 32 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" @@ -840,6 +864,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" #line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" ;; Updates restore point to the given HL mem. address + push namespace core __RESTORE: PROC LOCAL __DATA_ADDR @@ -1116,32 +1141,35 @@ __09_decode_float: __DATA_ADDR: ;; Stores current DATA ptr dw __DATA__0 ENDP + pop namespace #line 28 "restore3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 29 "restore3.bas" END diff --git a/tests/functional/rnd.asm b/tests/functional/rnd.asm index 4504fb5e1..b4e5fd2b4 100644 --- a/tests/functional/rnd.asm +++ b/tests/functional/rnd.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,32 +8,32 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, 0 ld hl, 0 - call RANDOMIZE - call RND + call core.RANDOMIZE + call core.RND ld hl, _a - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,6 +45,7 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/random.asm" ; RANDOM functions + push namespace core RANDOMIZE: ; Randomize with 32 bit seed in DE HL ; if SEED = 0, calls ROM to take frames as seed @@ -141,32 +142,35 @@ RND_LOOP: ld a, l ; exponent in A ret ENDP + pop namespace #line 23 "rnd.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 24 "rnd.bas" END diff --git a/tests/functional/save.asm b/tests/functional/save.asm index 8d7651406..3091de62c 100644 --- a/tests/functional/save.asm +++ b/tests/functional/save.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 16384 push hl ld hl, 6912 push hl - call SAVE_CODE + call core.SAVE_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -118,6 +118,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -147,6 +148,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -212,9 +214,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -222,37 +225,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -265,125 +269,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 31 "save.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ; Save code "XXX" at address YYY of length ZZZ @@ -458,95 +466,98 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/save.asm" + push namespace core SAVE_CODE: PROC LOCAL MEMBOT @@ -556,7 +567,7 @@ SAVE_CODE: LOCAL SAVE_STOP LOCAL STR_PTR LOCAL SAVE_EMPTY_ERROR -#line 24 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 26 "/zxbasic/src/arch/zx48k/library-asm/save.asm" MEMBOT EQU 23698 ; Use the CALC mem to store header STR_PTR EQU MEMBOT + 17 pop hl ; Return address @@ -688,7 +699,8 @@ SA_CHK_BRK: rra ld a, b ret -#line 181 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 183 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ENDP + pop namespace #line 32 "save.bas" END diff --git a/tests/functional/save01.asm b/tests/functional/save01.asm index 0263ee4ca..2e080a8f2 100644 --- a/tests/functional/save01.asm +++ b/tests/functional/save01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, 32768 push hl ld hl, 25 push hl - call SAVE_CODE + call core.SAVE_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -122,6 +122,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -151,6 +152,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -216,9 +218,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -226,37 +229,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -269,125 +273,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 35 "save01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ; Save code "XXX" at address YYY of length ZZZ @@ -462,95 +470,98 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/save.asm" + push namespace core SAVE_CODE: PROC LOCAL MEMBOT @@ -560,7 +571,7 @@ SAVE_CODE: LOCAL SAVE_STOP LOCAL STR_PTR LOCAL SAVE_EMPTY_ERROR -#line 24 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 26 "/zxbasic/src/arch/zx48k/library-asm/save.asm" MEMBOT EQU 23698 ; Use the CALC mem to store header STR_PTR EQU MEMBOT + 17 pop hl ; Return address @@ -692,7 +703,8 @@ SA_CHK_BRK: rra ld a, b ret -#line 181 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 183 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ENDP + pop namespace #line 36 "save01.bas" END diff --git a/tests/functional/save02.asm b/tests/functional/save02.asm index d2e4b6fd4..12becb7dc 100644 --- a/tests/functional/save02.asm +++ b/tests/functional/save02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _variableToSave: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, _variableToSave push hl ld hl, 2 push hl - call SAVE_CODE + call core.SAVE_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -121,6 +121,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -150,6 +151,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -215,9 +217,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -225,37 +228,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -268,125 +272,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 32 "save02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ; Save code "XXX" at address YYY of length ZZZ @@ -461,95 +469,98 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/save.asm" + push namespace core SAVE_CODE: PROC LOCAL MEMBOT @@ -559,7 +570,7 @@ SAVE_CODE: LOCAL SAVE_STOP LOCAL STR_PTR LOCAL SAVE_EMPTY_ERROR -#line 24 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 26 "/zxbasic/src/arch/zx48k/library-asm/save.asm" MEMBOT EQU 23698 ; Use the CALC mem to store header STR_PTR EQU MEMBOT + 17 pop hl ; Return address @@ -691,7 +702,8 @@ SA_CHK_BRK: rra ld a, b ret -#line 181 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 183 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ENDP + pop namespace #line 33 "save02.bas" END diff --git a/tests/functional/save03.asm b/tests/functional/save03.asm index 0a7092c5b..fb7f7b04d 100644 --- a/tests/functional/save03.asm +++ b/tests/functional/save03.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,37 +8,37 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl ld hl, __LABEL__.ZXBASIC_USER_DATA push hl ld hl, __LABEL__.ZXBASIC_USER_DATA_LEN push hl - call SAVE_CODE + call core.SAVE_CODE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -118,6 +118,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -147,6 +148,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -212,9 +214,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -222,37 +225,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -265,125 +269,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 31 "save03.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ; Save code "XXX" at address YYY of length ZZZ @@ -458,95 +466,98 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/save.asm" + push namespace core SAVE_CODE: PROC LOCAL MEMBOT @@ -556,7 +567,7 @@ SAVE_CODE: LOCAL SAVE_STOP LOCAL STR_PTR LOCAL SAVE_EMPTY_ERROR -#line 24 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 26 "/zxbasic/src/arch/zx48k/library-asm/save.asm" MEMBOT EQU 23698 ; Use the CALC mem to store header STR_PTR EQU MEMBOT + 17 pop hl ; Return address @@ -688,7 +699,8 @@ SA_CHK_BRK: rra ld a, b ret -#line 181 "/zxbasic/src/arch/zx48k/library-asm/save.asm" +#line 183 "/zxbasic/src/arch/zx48k/library-asm/save.asm" ENDP + pop namespace #line 32 "save03.bas" END diff --git a/tests/functional/sgnf.asm b/tests/functional/sgnf.asm index 29638ee5b..7c6888a4c 100644 --- a/tests/functional/sgnf.asm +++ b/tests/functional/sgnf.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 81h DEFB 00h DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_y) ld de, (_y + 1) ld bc, (_y + 3) - call __SGNF + call core.__SGNF ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,6 +49,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgnf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgn.asm" ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core PROC LOCAL __ENDSGN __SGNF: @@ -61,25 +62,26 @@ __SGNF: jr __ENDSGN __SGNF16: __SGNI32: - ld a, h - or l - or e - or d - ret z + ld a, h + or l + or e + or d + ret z ld a, d jr __ENDSGN __SGNI16: - ld a, h - or l - ret z - ld a, h + ld a, h + or l + ret z + ld a, h __ENDSGN: - or a - ld a, 1 - ret p - neg - ret + or a + ld a, 1 + ret p + neg + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/sgnf.asm" #line 22 "sgnf.bas" END diff --git a/tests/functional/sgnf16.asm b/tests/functional/sgnf16.asm index 6d655787d..80e5b5683 100644 --- a/tests/functional/sgnf16.asm +++ b/tests/functional/sgnf16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 00h DEFB 00h DEFB 01h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) ld de, (_y + 2) - call __SGNF16 + call core.__SGNF16 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,6 +47,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgnf16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgn.asm" ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core PROC LOCAL __ENDSGN __SGNF: @@ -59,25 +60,26 @@ __SGNF: jr __ENDSGN __SGNF16: __SGNI32: - ld a, h - or l - or e - or d - ret z + ld a, h + or l + or e + or d + ret z ld a, d jr __ENDSGN __SGNI16: - ld a, h - or l - ret z - ld a, h + ld a, h + or l + ret z + ld a, h __ENDSGN: - or a - ld a, 1 - ret p - neg - ret + or a + ld a, 1 + ret p + neg + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/sgnf16.asm" #line 21 "sgnf16.bas" END diff --git a/tests/functional/sgni16.asm b/tests/functional/sgni16.asm index d8528c597..25d391b6f 100644 --- a/tests/functional/sgni16.asm +++ b/tests/functional/sgni16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 01h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) - call __SGNI16 + call core.__SGNI16 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -44,6 +44,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgni16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgn.asm" ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core PROC LOCAL __ENDSGN __SGNF: @@ -56,25 +57,26 @@ __SGNF: jr __ENDSGN __SGNF16: __SGNI32: - ld a, h - or l - or e - or d - ret z + ld a, h + or l + or e + or d + ret z ld a, d jr __ENDSGN __SGNI16: - ld a, h - or l - ret z - ld a, h + ld a, h + or l + ret z + ld a, h __ENDSGN: - or a - ld a, 1 - ret p - neg - ret + or a + ld a, 1 + ret p + neg + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/sgni16.asm" #line 20 "sgni16.bas" END diff --git a/tests/functional/sgni32.asm b/tests/functional/sgni32.asm index 21dacb448..def5b5712 100644 --- a/tests/functional/sgni32.asm +++ b/tests/functional/sgni32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 01h DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) ld de, (_y + 2) - call __SGNI32 + call core.__SGNI32 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -47,6 +47,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgni32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgn.asm" ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core PROC LOCAL __ENDSGN __SGNF: @@ -59,25 +60,26 @@ __SGNF: jr __ENDSGN __SGNF16: __SGNI32: - ld a, h - or l - or e - or d - ret z + ld a, h + or l + or e + or d + ret z ld a, d jr __ENDSGN __SGNI16: - ld a, h - or l - ret z - ld a, h + ld a, h + or l + ret z + ld a, h __ENDSGN: - or a - ld a, 1 - ret p - neg - ret + or a + ld a, 1 + ret p + neg + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/sgni32.asm" #line 21 "sgni32.bas" END diff --git a/tests/functional/sgni8.asm b/tests/functional/sgni8.asm index aae8db955..01150b6a2 100644 --- a/tests/functional/sgni8.asm +++ b/tests/functional/sgni8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_y) - call __SGNI8 + call core.__SGNI8 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,12 +42,14 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgni8.asm" ; Returns SGN (SIGN) for 8 bits signed integer + push namespace core __SGNI8: - or a - ret z - ld a, 1 - ret p - neg - ret + or a + ret z + ld a, 1 + ret p + neg + ret + pop namespace #line 20 "sgni8.bas" END diff --git a/tests/functional/sgnu16.asm b/tests/functional/sgnu16.asm index 2de4fe379..b1cf22a84 100644 --- a/tests/functional/sgnu16.asm +++ b/tests/functional/sgnu16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 01h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) - call __SGNU16 + call core.__SGNU16 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -43,11 +43,13 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgnu16.asm" ; Returns SGN (SIGN) for 16 bits unsigned integer + push namespace core __SGNU16: - ld a, h - or l - ret z - ld a, 1 - ret + ld a, h + or l + ret z + ld a, 1 + ret + pop namespace #line 20 "sgnu16.bas" END diff --git a/tests/functional/sgnu32.asm b/tests/functional/sgnu32.asm index 7491285a1..53769dc04 100644 --- a/tests/functional/sgnu32.asm +++ b/tests/functional/sgnu32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 01h DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_y) ld de, (_y + 2) - call __SGNU32 + call core.__SGNU32 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,13 +46,15 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgnu32.asm" ; Returns SGN (SIGN) for 32 bits unsigned integer + push namespace core __SGNU32: - ld a, h - or l - or d - or e - ret z - ld a, 1 - ret + ld a, h + or l + or d + or e + ret z + ld a, 1 + ret + pop namespace #line 21 "sgnu32.bas" END diff --git a/tests/functional/sgnu8.asm b/tests/functional/sgnu8.asm index 78ee73f7d..b2f3a1c32 100644 --- a/tests/functional/sgnu8.asm +++ b/tests/functional/sgnu8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _y: DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_y) - call __SGNU8 + call core.__SGNU8 ld (0), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -42,10 +42,12 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/sgnu8.asm" ; Returns SGN (SIGN) for 8 bits unsigned integera + push namespace core __SGNU8: - or a + or a ret z - ld a, 1 - ret + ld a, 1 + ret + pop namespace #line 20 "sgnu8.bas" END diff --git a/tests/functional/shl8.asm b/tests/functional/shl8.asm index 9c2d01b33..9560cc377 100644 --- a/tests/functional/shl8.asm +++ b/tests/functional/shl8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) or a @@ -41,9 +41,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/shl_shr_16bit.asm b/tests/functional/shl_shr_16bit.asm index 6cc8d5bba..4a2ca6c90 100644 --- a/tests/functional/shl_shr_16bit.asm +++ b/tests/functional/shl_shr_16bit.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00h _result: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 32767 ld (_result), hl ld a, (_a) @@ -77,9 +77,9 @@ __LABEL7: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/shl_shr_32bit.asm b/tests/functional/shl_shr_32bit.asm index d4c5b3531..8906760fc 100644 --- a/tests/functional/shl_shr_32bit.asm +++ b/tests/functional/shl_shr_32bit.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00h _c: @@ -32,20 +32,20 @@ _d: DEFB 0FFh _result: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_c) ld de, (_c + 2) ld (_result), hl ld hl, (_c) ld de, (_c + 2) - call __SHRL32 + call core.__SHRL32 ld (_result), hl ld hl, (_c) ld de, (_c + 2) ld b, 2 __LABEL0: - call __SHRL32 + call core.__SHRL32 djnz __LABEL0 ld (_result), hl ld a, (_a) @@ -55,7 +55,7 @@ __LABEL0: or a jr z, __LABEL2 __LABEL1: - call __SHRL32 + call core.__SHRL32 djnz __LABEL1 __LABEL2: ld (_result), hl @@ -64,13 +64,13 @@ __LABEL2: ld (_result), hl ld hl, (_c) ld de, (_c + 2) - call __SHL32 + call core.__SHL32 ld (_result), hl ld hl, (_c) ld de, (_c + 2) ld b, 2 __LABEL3: - call __SHL32 + call core.__SHL32 djnz __LABEL3 ld (_result), hl ld a, (_a) @@ -80,7 +80,7 @@ __LABEL3: or a jr z, __LABEL5 __LABEL4: - call __SHL32 + call core.__SHL32 djnz __LABEL4 __LABEL5: ld (_result), hl @@ -89,13 +89,13 @@ __LABEL5: ld (_result), hl ld hl, (_d) ld de, (_d + 2) - call __SHRA32 + call core.__SHRA32 ld (_result), hl ld hl, (_d) ld de, (_d + 2) ld b, 2 __LABEL6: - call __SHRA32 + call core.__SHRA32 djnz __LABEL6 ld (_result), hl ld a, (_a) @@ -105,7 +105,7 @@ __LABEL6: or a jr z, __LABEL8 __LABEL7: - call __SHRA32 + call core.__SHRA32 djnz __LABEL7 __LABEL8: ld (_result), hl @@ -114,13 +114,13 @@ __LABEL8: ld (_result), hl ld hl, (_d) ld de, (_d + 2) - call __SHL32 + call core.__SHL32 ld (_result), hl ld hl, (_d) ld de, (_d + 2) ld b, 2 __LABEL9: - call __SHL32 + call core.__SHL32 djnz __LABEL9 ld (_result), hl ld a, (_a) @@ -130,16 +130,16 @@ __LABEL9: or a jr z, __LABEL11 __LABEL10: - call __SHL32 + call core.__SHL32 djnz __LABEL10 __LABEL11: ld (_result), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -150,27 +150,33 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/shl32.asm" + push namespace core __SHL32: ; Left Logical Shift 32 bits - sla l - rl h - rl e - rl d + sla l + rl h + rl e + rl d ret + pop namespace #line 117 "shl_shr_32bit.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/shra32.asm" + push namespace core __SHRA32: ; Right Arithmetical Shift 32 bits sra d rr e rr h rr l ret + pop namespace #line 118 "shl_shr_32bit.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/shrl32.asm" + push namespace core __SHRL32: ; Right Logical Shift 32 bits srl d rr e rr h rr l ret + pop namespace #line 119 "shl_shr_32bit.bas" END diff --git a/tests/functional/shri8.asm b/tests/functional/shri8.asm index 820cedae3..9eb1faa27 100644 --- a/tests/functional/shri8.asm +++ b/tests/functional/shri8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) or a @@ -41,9 +41,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/shru8.asm b/tests/functional/shru8.asm index a8371b42f..8d37289fb 100644 --- a/tests/functional/shru8.asm +++ b/tests/functional/shru8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) or a @@ -41,9 +41,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/sigilfunc.asm b/tests/functional/sigilfunc.asm index 0b34acd16..b8f7d662d 100644 --- a/tests/functional/sigilfunc.asm +++ b/tests/functional/sigilfunc.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,7 +50,7 @@ _test: ld ix, 0 add ix, sp ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR _test__leave: ld sp, ix pop ix @@ -122,6 +122,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -151,6 +152,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -216,9 +218,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -226,37 +229,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -269,125 +273,129 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 33 "sigilfunc.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -464,118 +472,122 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 34 "sigilfunc.bas" END diff --git a/tests/functional/simple.asm b/tests/functional/simple.asm index 7813b252a..17b5dbc55 100644 --- a/tests/functional/simple.asm +++ b/tests/functional/simple.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 xor a - call __PRINTSTR - call PRINT_EOL + call core.__PRINTSTR + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -65,70 +65,75 @@ __LABEL0: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -158,49 +163,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -208,319 +219,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -575,422 +606,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 34 "simple.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1117,9 +1151,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1127,37 +1162,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1167,134 +1203,138 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 35 "simple.bas" END diff --git a/tests/functional/slice0.asm b/tests/functional/slice0.asm index 7353f7a77..21a413fa1 100644 --- a/tests/functional/slice0.asm +++ b/tests/functional/slice0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) push hl ld hl, 10 @@ -34,16 +34,16 @@ __MAIN_PROGRAM__: ld hl, 65534 push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -184,9 +184,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -194,37 +195,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -234,119 +236,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 28 "slice0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -366,15 +372,17 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -439,6 +447,7 @@ __STRLEN: ; Direct FASTCALL entry #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -468,6 +477,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -480,159 +490,163 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 19 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 29 "slice0.bas" END diff --git a/tests/functional/slice2.asm b/tests/functional/slice2.asm index 161c98f80..8b51f8bd6 100644 --- a/tests/functional/slice2.asm +++ b/tests/functional/slice2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call CLS +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.CLS ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl xor a push af @@ -35,13 +35,13 @@ __MAIN_PROGRAM__: push af call _doubleSizePrint ld a, 8 - call __STOP + call core.__STOP ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -53,7 +53,7 @@ __END_PROGRAM: ld hl, 0 ld b, h ld c, l - jp __END_PROGRAM + jp core.__END_PROGRAM _doubleSizePrint: push ix ld ix, 0 @@ -77,11 +77,11 @@ __LABEL4: ld h, 0 push hl xor a - call __STRSLICE + call core.__STRSLICE ld d, h ld e, l ld bc, -3 - call __PSTORE_STR2 + call core.__PSTORE_STR2 ld a, (ix+7) add a, 2 ld (ix+7), a @@ -92,7 +92,7 @@ __LABEL1: push af ld l, (ix+8) ld h, (ix+9) - call __STRLEN + call core.__STRLEN dec hl ld a, l pop hl @@ -104,10 +104,10 @@ _doubleSizePrint__leave: exx ld l, (ix+8) ld h, (ix+9) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-3) ld h, (ix-2) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -140,64 +140,69 @@ __LABEL0: ; Our faster implementation #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 110 "slice2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -227,6 +232,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 111 "slice2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -352,9 +358,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -362,37 +369,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -402,94 +410,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 112 "slice2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -563,125 +573,129 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 113 "slice2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" ; vim:ts=4:et:sw=4 @@ -697,50 +711,56 @@ __LOADSTR: ; __FASTCALL__ entry ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/pstorestr2.asm" + push namespace core __PSTORE_STR2: push ix pop hl add hl, bc jp __STORE_STR2 + pop namespace #line 114 "slice2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 115 "slice2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -756,74 +776,76 @@ __STRLEN: ; Direct FASTCALL entry ; it in dynamic memory if needed). Returns pointer (HL) to resulting ; string. NULL (0) if no memory for padding. ; + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 116 "slice2.bas" END diff --git a/tests/functional/spfill.asm b/tests/functional/spfill.asm index 0163b392c..970436370 100644 --- a/tests/functional/spfill.asm +++ b/tests/functional/spfill.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: - call CLS + call core.CLS __LABEL__20: ld a, 128 push af ld a, 87 push af ld a, 87 - call CIRCLE + call core.CIRCLE __LABEL__30: ld hl, __LABEL0 xor a - call USR_STR + call core.USR_STR push hl ld a, 87 push af @@ -45,13 +45,13 @@ __LABEL__30: call _SPFill __LABEL__40: ld hl, 0 - call __PAUSE + call core.__PAUSE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,6 +76,7 @@ _SPFill: pop ix ret #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelUp.asm" + push namespace core SP.PixelUp: ld a,h dec h @@ -96,8 +97,10 @@ _SPFill: ld h,a cp $40 ret + pop namespace #line 31 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/PixelDown.asm" + push namespace core SP.PixelDown: inc h ld a,h @@ -119,8 +122,10 @@ _SPFill: cp $58 ccf ret + pop namespace #line 32 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/CharLeft.asm" + push namespace core SP.CharLeft: ld a,l dec l @@ -131,8 +136,10 @@ _SPFill: ld h,a cp $40 ret + pop namespace #line 33 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/CharRight.asm" + push namespace core SP.CharRight: inc l ret nz @@ -142,8 +149,10 @@ _SPFill: cp $58 ccf ret + pop namespace #line 34 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/SP/GetScrnAddr.asm" + push namespace core SPGetScrnAddr: and $07 or $40 @@ -175,6 +184,7 @@ norotate: or l ld e,a ret + pop namespace #line 35 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" SPPFill_IXBuffer: DEFB 0,0 @@ -484,7 +494,7 @@ endapply: SPPFill_end: LD IX,(SPPFill_IXBuffer) ENDP -#line 840 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" +#line 863 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" _SPFill__leave: ret __LABEL0: @@ -497,6 +507,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -526,6 +537,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" ; MIXED __FASTCAL__ / __CALLE__ PLOT Function @@ -535,93 +547,100 @@ __STOP: #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -629,7 +648,9 @@ __CLS_SCR: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -684,29 +705,31 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + push namespace core PLOT: - PROC - LOCAL PLOT_SUB - LOCAL PIXEL_ADDR - LOCAL COORDS - LOCAL __PLOT_ERR + PROC + LOCAL PLOT_SUB + LOCAL PIXEL_ADDR + LOCAL COORDS + LOCAL __PLOT_ERR LOCAL P_FLAG LOCAL __PLOT_OVER1 P_FLAG EQU 23697 - pop hl - ex (sp), hl ; Callee - ld b, a - ld c, h -#line 35 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" -#line 41 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" - ld a, 191 - cp b - jr c, __PLOT_ERR ; jr is faster here (#1) + pop hl + ex (sp), hl ; Callee + ld b, a + ld c, h +#line 37 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" +#line 43 "/zxbasic/src/arch/zx48k/library-asm/plot.asm" + ld a, 191 + cp b + jr c, __PLOT_ERR ; jr is faster here (#1) __PLOT: ; __FASTCALL__ entry (b, c) = pixel coords (y, x) - ld (COORDS), bc ; Saves current point - ld a, 191 ; Max y coord - call PIXEL_ADDR + ld (COORDS), bc ; Saves current point + ld a, 191 ; Max y coord + call PIXEL_ADDR res 6, h ; Starts from 0 ld bc, (SCREEN_ADDR) add hl, bc ; Now current offset @@ -738,181 +761,186 @@ __PLOT_ERR: PLOT_SUB EQU 22ECh PIXEL_ADDR EQU 22ACh COORDS EQU 5C7Dh - ENDP + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" ; Draws a circle at X, Y of radius R ; X, Y on the Stack, R in accumulator (Byte) - PROC - LOCAL __CIRCLE_ERROR - LOCAL __CIRCLE_LOOP - LOCAL __CIRCLE_NEXT + push namespace core + PROC + LOCAL __CIRCLE_ERROR + LOCAL __CIRCLE_LOOP + LOCAL __CIRCLE_NEXT __CIRCLE_ERROR: - jp __OUT_OF_SCREEN_ERR + jp __OUT_OF_SCREEN_ERR CIRCLE: - ;; Entry point - pop hl ; Return Address - pop de ; D = Y - ex (sp), hl ; __CALLEE__ convention - ld e, h ; E = X - ld h, a ; H = R -#line 31 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" - ld a, h - add a, d - sub 192 - jr nc, __CIRCLE_ERROR - ld a, d - sub h - jr c, __CIRCLE_ERROR - ld a, e - sub h - jr c, __CIRCLE_ERROR - ld a, h - add a, e - jr c, __CIRCLE_ERROR + ;; Entry point + pop hl ; Return Address + pop de ; D = Y + ex (sp), hl ; __CALLEE__ convention + ld e, h ; E = X + ld h, a ; H = R +#line 33 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" +#line 39 "/zxbasic/src/arch/zx48k/library-asm/circle.asm" + ld a, h + add a, d + sub 192 + jr nc, __CIRCLE_ERROR + ld a, d + sub h + jr c, __CIRCLE_ERROR + ld a, e + sub h + jr c, __CIRCLE_ERROR + ld a, h + add a, e + jr c, __CIRCLE_ERROR ; __FASTCALL__ Entry: D, E = Y, X point of the center ; A = Radious __CIRCLE: - push de - ld a, h - exx - pop de ; D'E' = x0, y0 - ld h, a ; H' = r - ld c, e - ld a, h - add a, d - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 + r) - ld b, d - ld a, h - add a, e - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 + r, y0) - ld c, e - ld a, d - sub h - ld b, a - call __CIRCLE_PLOT ; PLOT (x0, y0 - r) - ld b, d - ld a, e - sub h - ld c, a - call __CIRCLE_PLOT ; PLOT (x0 - r, y0) - exx - ld b, 0 ; B = x = 0 - ld c, h ; C = y = Radius - ld hl, 1 - or a - sbc hl, bc ; HL = f = 1 - radius - ex de, hl - ld hl, 0 - or a - sbc hl, bc ; HL = -radius - add hl, hl ; HL = -2 * radius - ex de, hl ; DE = -2 * radius = ddF_y, HL = f - xor a ; A = ddF_x = 0 - ex af, af' ; Saves it + push de + ld a, h + exx + pop de ; D'E' = x0, y0 + ld h, a ; H' = r + ld c, e + ld a, h + add a, d + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 + r) + ld b, d + ld a, h + add a, e + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 + r, y0) + ld c, e + ld a, d + sub h + ld b, a + call __CIRCLE_PLOT ; PLOT (x0, y0 - r) + ld b, d + ld a, e + sub h + ld c, a + call __CIRCLE_PLOT ; PLOT (x0 - r, y0) + exx + ld b, 0 ; B = x = 0 + ld c, h ; C = y = Radius + ld hl, 1 + or a + sbc hl, bc ; HL = f = 1 - radius + ex de, hl + ld hl, 0 + or a + sbc hl, bc ; HL = -radius + add hl, hl ; HL = -2 * radius + ex de, hl ; DE = -2 * radius = ddF_y, HL = f + xor a ; A = ddF_x = 0 + ex af, af' ; Saves it __CIRCLE_LOOP: - ld a, b - cp c - ret nc ; Returns when x >= y - bit 7, h ; HL >= 0? : if (f >= 0)... - jp nz, __CIRCLE_NEXT - dec c ; y-- - inc de - inc de ; ddF_y += 2 - add hl, de ; f += ddF_y + ld a, b + cp c + ret nc ; Returns when x >= y + bit 7, h ; HL >= 0? : if (f >= 0)... + jp nz, __CIRCLE_NEXT + dec c ; y-- + inc de + inc de ; ddF_y += 2 + add hl, de ; f += ddF_y __CIRCLE_NEXT: - inc b ; x++ - ex af, af' - add a, 2 ; 1 Cycle faster than inc a, inc a - inc hl ; f++ - push af - add a, l - ld l, a - ld a, h - adc a, 0 ; f = f + ddF_x - ld h, a - pop af - ex af, af' - push bc - exx - pop hl ; H'L' = Y, X - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) - ld a, d - add a, h - ld b, a ; B = y0 + y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - add a, l - ld c, a ; C = x0 + x - call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) - ld a, d - sub h - ld b, a ; B = y0 - y - ld a, e - sub l - ld c, a ; C = x0 - x - call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) - ld a, d - add a, l - ld b, a ; B = y0 + x - ld a, e - sub h - ld c, a ; C = x0 - y - call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - add a, h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) - ld a, d - sub l - ld b, a ; B = y0 - x - ld a, e - sub h - ld c, a ; C = x0 + y - call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) - exx - jp __CIRCLE_LOOP + inc b ; x++ + ex af, af' + add a, 2 ; 1 Cycle faster than inc a, inc a + inc hl ; f++ + push af + add a, l + ld l, a + ld a, h + adc a, 0 ; f = f + ddF_x + ld h, a + pop af + ex af, af' + push bc + exx + pop hl ; H'L' = Y, X + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 + y) + ld a, d + add a, h + ld b, a ; B = y0 + y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 + y) + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + add a, l + ld c, a ; C = x0 + x + call __CIRCLE_PLOT ; plot(x0 + x, y0 - y) + ld a, d + sub h + ld b, a ; B = y0 - y + ld a, e + sub l + ld c, a ; C = x0 - x + call __CIRCLE_PLOT ; plot(x0 - x, y0 - y) + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 + x) + ld a, d + add a, l + ld b, a ; B = y0 + x + ld a, e + sub h + ld c, a ; C = x0 - y + call __CIRCLE_PLOT ; plot(x0 - y, y0 + x) + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + add a, h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 + y, y0 - x) + ld a, d + sub l + ld b, a ; B = y0 - x + ld a, e + sub h + ld c, a ; C = x0 + y + call __CIRCLE_PLOT ; plot(x0 - y, y0 - x) + exx + jp __CIRCLE_LOOP __CIRCLE_PLOT: - ; Plots a point of the circle, preserving HL and DE - push hl - push de - call __PLOT - pop de - pop hl - ret - ENDP -#line 468 "spfill.bas" + ; Plots a point of the circle, preserving HL and DE + push hl + push de + call __PLOT + pop de + pop hl + ret + ENDP + pop namespace +#line 871 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pause.asm" ; The PAUSE statement (Calling the ROM) + push namespace core __PAUSE: - ld b, h + ld b, h ld c, l jp 1F3Dh ; PAUSE_1 -#line 470 "spfill.bas" + pop namespace +#line 873 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/usr_str.asm" ; This function just returns the address of the UDG of the given str. ; If the str is EMPTY or not a letter, 0 is returned and ERR_NR set @@ -1043,9 +1071,10 @@ __PAUSE: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1053,37 +1082,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1093,124 +1123,127 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/usr_str.asm" + push namespace core USR_STR: PROC ex af, af' ; Saves A flag - ld a, h - or l - jr z, USR_ERROR ; a$ = NULL => Invalid Arg + ld a, h + or l + jr z, USR_ERROR ; a$ = NULL => Invalid Arg ld d, h ; Saves HL in DE, for ld e, l ; later usage - ld c, (hl) - inc hl - ld a, (hl) - or c - jr z, USR_ERROR ; a$ = "" => Invalid Arg - inc hl - ld a, (hl) ; Only the 1st char is needed - and 11011111b ; Convert it to UPPER CASE - sub 144 ; CODE(UDG "A") - jr nc, CONT - add a, 144 ; It was a letter - sub 'A' + ld c, (hl) + inc hl + ld a, (hl) + or c + jr z, USR_ERROR ; a$ = "" => Invalid Arg + inc hl + ld a, (hl) ; Only the 1st char is needed + and 11011111b ; Convert it to UPPER CASE + sub 144 ; CODE(UDG "A") + jr nc, CONT + add a, 144 ; It was a letter + sub 'A' LOCAL CONT CONT: - ld l, a - ld h, 0 - add hl, hl - add hl, hl - add hl, hl ; hl = A * 8 - ld bc, (UDG) - add hl, bc + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, hl ; hl = A * 8 + ld bc, (UDG) + add hl, bc ;; Now checks if the string must be released ex af, af' ; Recovers A flag or a @@ -1219,16 +1252,17 @@ CONT: ex de, hl ; Recovers original HL value call __MEM_FREE pop hl - ret + ret USR_ERROR: ex de, hl ; Recovers original HL value ex af, af' ; Recovers A flag or a call nz, __MEM_FREE - ld a, ERROR_InvalidArg - ld (ERR_NR), a - ld hl, 0 - ret - ENDP -#line 471 "spfill.bas" + ld a, ERROR_InvalidArg + ld (ERR_NR), a + ld hl, 0 + ret + ENDP + pop namespace +#line 874 "/zxbasic/src/arch/zx48k/library/SP/Fill.bas" END diff --git a/tests/functional/stoperr.asm b/tests/functional/stoperr.asm index 4e56ef4f5..18166be2c 100644 --- a/tests/functional/stoperr.asm +++ b/tests/functional/stoperr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 8 - call __STOP + call core.__STOP ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -37,11 +37,12 @@ __END_PROGRAM: ei ret ld a, 255 - call __ERROR + call core.__ERROR ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -71,5 +72,6 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 21 "stoperr.bas" END diff --git a/tests/functional/storecstr.asm b/tests/functional/storecstr.asm index 73f9ecacd..5e5acd380 100644 --- a/tests/functional/storecstr.asm +++ b/tests/functional/storecstr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _f - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -127,6 +127,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -156,6 +157,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -281,9 +283,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -291,37 +294,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -334,90 +338,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -487,94 +493,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -596,132 +604,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -746,5 +759,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 27 "storecstr.bas" END diff --git a/tests/functional/storef.asm b/tests/functional/storef.asm index 58437edee..a8b3db552 100644 --- a/tests/functional/storef.asm +++ b/tests/functional/storef.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00, 00, 00, 00, 00 _miny: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_miny) ld de, (_miny + 1) ld bc, (_miny + 3) ld hl, _f - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -45,30 +45,32 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 22 "storef.bas" END diff --git a/tests/functional/storestr0.asm b/tests/functional/storestr0.asm index d025197fb..6c6883376 100644 --- a/tests/functional/storestr0.asm +++ b/tests/functional/storestr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00, 00 _miny: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_miny) ld hl, _f - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -122,6 +122,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -151,6 +152,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -276,9 +278,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -286,37 +289,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -329,90 +333,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -482,94 +488,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -591,132 +599,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -741,5 +754,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 20 "storestr0.bas" END diff --git a/tests/functional/storestr1.asm b/tests/functional/storestr1.asm index de4dfc212..f542867cc 100644 --- a/tests/functional/storestr1.asm +++ b/tests/functional/storestr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,25 +50,25 @@ _test: push hl ld de, __LABEL0 ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR ld de, (_a) ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-4) ld h, (ix-3) ld d, h ld e, l ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-4) ld h, (ix-3) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -206,9 +206,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -216,37 +217,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -256,94 +258,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 57 "storestr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -426,6 +430,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -455,6 +460,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -527,90 +533,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -632,132 +640,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -782,11 +795,14 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 58 "storestr1.bas" END diff --git a/tests/functional/storestr2.asm b/tests/functional/storestr2.asm index 130c61666..9ad56df83 100644 --- a/tests/functional/storestr2.asm +++ b/tests/functional/storestr2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,28 +49,28 @@ _test: push hl ld de, __LABEL0 ld bc, 4 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-2) ld h, (ix-1) ld d, h ld e, l ld bc, 4 - call __PSTORE_STR + call core.__PSTORE_STR ld de, (_a) ld bc, 4 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-2) ld h, (ix-1) - call __LOADSTR + call core.__LOADSTR _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -212,9 +212,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -222,37 +223,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -262,94 +264,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 63 "storestr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -415,6 +419,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -444,6 +449,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -456,125 +462,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 64 "storestr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -674,132 +684,137 @@ __LOADSTR: ; __FASTCALL__ entry ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -824,11 +839,14 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 65 "storestr2.bas" END diff --git a/tests/functional/storeu16.asm b/tests/functional/storeu16.asm index bfa5e3c52..74c4db6d5 100644 --- a/tests/functional/storeu16.asm +++ b/tests/functional/storeu16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00, 00 _miny: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_miny) ld (_f), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/storeu32.asm b/tests/functional/storeu32.asm index 8808b62ce..04f5e11f2 100644 --- a/tests/functional/storeu32.asm +++ b/tests/functional/storeu32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00, 00, 00, 00 _miny: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_miny) ld de, (_miny + 2) ld (_f), hl @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/storeu8.asm b/tests/functional/storeu8.asm index ff1ed4ae1..d8a9c58e8 100644 --- a/tests/functional/storeu8.asm +++ b/tests/functional/storeu8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _f: DEFB 00 _miny: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_miny) ld (_f), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/str0.asm b/tests/functional/str0.asm index f747d2b35..e4325937c 100644 --- a/tests/functional/str0.asm +++ b/tests/functional/str0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,40 +8,40 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 1 ld (_a), a inc a - call __U8TOFREG - call __STR_FAST + call core.__U8TOFREG + call core.__STR_FAST push hl call _test - call __MEM_FREE + call core.__MEM_FREE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -57,20 +57,20 @@ _test: ld l, (ix+4) ld h, (ix+5) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR ld l, (ix+4) ld h, (ix+5) push hl ld de, __LABEL0 pop hl - call __ADDSTR + call core.__ADDSTR _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -208,9 +208,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -218,37 +219,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -258,94 +260,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 58 "str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -357,70 +361,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -450,49 +459,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -500,319 +515,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -867,468 +902,475 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 59 "str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 60 "str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation @@ -1406,101 +1448,104 @@ __PRINT_STR: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -1515,270 +1560,281 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" + push namespace core __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - push bc - push de - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - pop de - pop bc - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - ex de, hl ; HL = start of original string - ldir ; Copies string content - pop de ; Original (ROM-CALC) string - pop bc ; Original Length + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + push bc + push de + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + pop de + pop bc + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + ex de, hl ; HL = start of original string + ldir ; Copies string content + pop de ; Original (ROM-CALC) string + pop bc ; Original Length __STR_END: - ex de, hl - inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result - ret + ex de, hl + inc bc + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + pop namespace #line 61 "str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 62 "str0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 63 "str0.bas" END diff --git a/tests/functional/str00.asm b/tests/functional/str00.asm index 3e759f415..2feacc7a7 100644 --- a/tests/functional/str00.asm +++ b/tests/functional/str00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -124,6 +124,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -153,6 +154,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -278,9 +280,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -288,37 +291,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -331,90 +335,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -484,94 +490,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -593,132 +601,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -743,5 +756,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 24 "str00.bas" END diff --git a/tests/functional/str01.asm b/tests/functional/str01.asm index 8c367ce26..c73c8d8cd 100644 --- a/tests/functional/str01.asm +++ b/tests/functional/str01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,40 +8,40 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00 _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 50 ld (_b), a - call __U8TOFREG - call __STR_FAST + call core.__U8TOFREG + call core.__STR_FAST ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -182,9 +182,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -192,37 +193,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -232,119 +234,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 24 "str01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation @@ -414,6 +420,7 @@ __STORE_STR2: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -443,6 +450,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -455,101 +463,104 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -564,22 +575,24 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -587,148 +600,155 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" + push namespace core __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - push bc - push de - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - pop de - pop bc - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - ex de, hl ; HL = start of original string - ldir ; Copies string content - pop de ; Original (ROM-CALC) string - pop bc ; Original Length + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + push bc + push de + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + pop de + pop bc + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + ex de, hl ; HL = start of original string + ldir ; Copies string content + pop de ; Original (ROM-CALC) string + pop bc ; Original Length __STR_END: - ex de, hl - inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result - ret + ex de, hl + inc bc + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + pop namespace #line 25 "str01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 26 "str01.bas" END diff --git a/tests/functional/str02.asm b/tests/functional/str02.asm index e814e50b0..e0f30f0bc 100644 --- a/tests/functional/str02.asm +++ b/tests/functional/str02.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,48 +8,48 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 02h DEFB 00h _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) ld de, 0 - call __U32TOFREG - call __STR_FAST + call core.__U32TOFREG + call core.__STR_FAST ex de, hl ld hl, __LABEL0 push de - call __ADDSTR + call core.__ADDSTR ex (sp), hl - call __MEM_FREE + call core.__MEM_FREE pop hl ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -191,9 +191,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -201,37 +202,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -241,94 +243,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 39 "str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -337,30 +341,32 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 40 "str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation @@ -430,6 +436,7 @@ __STORE_STR2: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -459,6 +466,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -471,101 +479,104 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -580,22 +591,24 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -603,257 +616,268 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" + push namespace core __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - push bc - push de - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - pop de - pop bc - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - ex de, hl ; HL = start of original string - ldir ; Copies string content - pop de ; Original (ROM-CALC) string - pop bc ; Original Length + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + push bc + push de + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + pop de + pop bc + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + ex de, hl ; HL = start of original string + ldir ; Copies string content + pop de ; Original (ROM-CALC) string + pop bc ; Original Length __STR_END: - ex de, hl - inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result - ret + ex de, hl + inc bc + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + pop namespace #line 41 "str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 42 "str02.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 43 "str02.bas" END diff --git a/tests/functional/str1.asm b/tests/functional/str1.asm index 2f26528f1..55556f491 100644 --- a/tests/functional/str1.asm +++ b/tests/functional/str1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -123,6 +123,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -152,6 +153,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -277,9 +279,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -287,37 +290,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -330,90 +334,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -483,94 +489,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -592,132 +600,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -742,5 +755,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 23 "str1.bas" END diff --git a/tests/functional/str_base0.asm b/tests/functional/str_base0.asm index a5dbbf56c..5729b7193 100644 --- a/tests/functional/str_base0.asm +++ b/tests/functional/str_base0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 4 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 4) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "str_base0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "str_base0.bas" END diff --git a/tests/functional/str_base1.asm b/tests/functional/str_base1.asm index e59067c36..ab7eebbb3 100644 --- a/tests/functional/str_base1.asm +++ b/tests/functional/str_base1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 4 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 4) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "str_base1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "str_base1.bas" END diff --git a/tests/functional/str_base2.asm b/tests/functional/str_base2.asm index faadcf120..18060b71c 100644 --- a/tests/functional/str_base2.asm +++ b/tests/functional/str_base2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 4 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 65533 push hl ld hl, (_a.__DATA__ + 4) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "str_base2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "str_base2.bas" END diff --git a/tests/functional/str_base3.asm b/tests/functional/str_base3.asm index 86ea9c036..b4cefa399 100644 --- a/tests/functional/str_base3.asm +++ b/tests/functional/str_base3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 4 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 4) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "str_base3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "str_base3.bas" END diff --git a/tests/functional/str_base4.asm b/tests/functional/str_base4.asm index 2bb119533..41d034937 100644 --- a/tests/functional/str_base4.asm +++ b/tests/functional/str_base4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 4 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 65533 push hl ld hl, (_a.__DATA__ + 4) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "str_base4.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "str_base4.bas" END diff --git a/tests/functional/str_base5.asm b/tests/functional/str_base5.asm index 2c2114214..9a33a96b2 100644 --- a/tests/functional/str_base5.asm +++ b/tests/functional/str_base5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 4 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 4) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "str_base5.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "str_base5.bas" END diff --git a/tests/functional/str_slash.asm b/tests/functional/str_slash.asm index 5282d0589..675daa0be 100644 --- a/tests/functional/str_slash.asm +++ b/tests/functional/str_slash.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _GetFileSize ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,7 +52,7 @@ _GetFileSize__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -205,9 +205,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -215,37 +216,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -255,94 +257,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 58 "str_slash.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -408,6 +412,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -437,6 +442,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -449,124 +455,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 59 "str_slash.bas" END diff --git a/tests/functional/stradd.asm b/tests/functional/stradd.asm index d4fdfb9f2..efcbba186 100644 --- a/tests/functional/stradd.asm +++ b/tests/functional/stradd.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,40 +8,40 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, (_a) - call __ADDSTR + call core.__ADDSTR ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -141,6 +141,7 @@ __LABEL1: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -170,6 +171,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -295,9 +297,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -305,37 +308,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -348,90 +352,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -501,94 +507,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -610,132 +618,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -760,6 +773,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "stradd.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -768,138 +782,144 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 42 "stradd.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 43 "stradd.bas" END diff --git a/tests/functional/strbase.asm b/tests/functional/strbase.asm index 343938b02..f36fbdb76 100644 --- a/tests/functional/strbase.asm +++ b/tests/functional/strbase.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,30 +8,30 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -41,7 +41,7 @@ __MAIN_PROGRAM__: ld hl, 0 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, (_a) push hl ld hl, 0 @@ -49,16 +49,16 @@ __MAIN_PROGRAM__: ld hl, 0 push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 50 "strbase.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,6 +905,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 51 "strbase.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -898,30 +914,32 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 52 "strbase.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -941,84 +959,88 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 53 "strbase.bas" END diff --git a/tests/functional/strbase2.asm b/tests/functional/strbase2.asm index 462ba82be..c1a1080e7 100644 --- a/tests/functional/strbase2.asm +++ b/tests/functional/strbase2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -42,7 +42,7 @@ __MAIN_PROGRAM__: ld hl, 0 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, (_a) push hl ld hl, 0 @@ -50,24 +50,24 @@ __MAIN_PROGRAM__: ld hl, 0 push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, (_a) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR ld hl, (_b) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -219,9 +219,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -229,37 +230,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -269,204 +271,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 58 "strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -478,70 +484,75 @@ __FREE_STR: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -571,49 +582,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -621,319 +638,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -988,468 +1025,475 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 59 "strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 60 "strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -1594,90 +1638,92 @@ __PRINT_STR: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -1699,132 +1745,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1849,6 +1900,7 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 61 "strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" ; Similar to __STORE_STR, but this one is called when @@ -1857,30 +1909,32 @@ __STORE_STR: ; HL = address of string memory variable ; DE = address of 2n string. It just copies DE into (HL) ; freeing (HL) previously. + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 62 "strbase2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -1900,84 +1954,88 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 63 "strbase2.bas" END diff --git a/tests/functional/strict2.asm b/tests/functional/strict2.asm index 52e88efb9..30cb8402a 100644 --- a/tests/functional/strict2.asm +++ b/tests/functional/strict2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,24 +8,24 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/strict_bool.asm b/tests/functional/strict_bool.asm index 0be6fc80c..7858167d3 100644 --- a/tests/functional/strict_bool.asm +++ b/tests/functional/strict_bool.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 083h ld de, 00020h ld bc, 00000h - call __LTF - call __NORMALIZE_BOOLEAN - call __U8TOFREG + call core.__LTF + call core.__NORMALIZE_BOOLEAN + call core.__U8TOFREG ld hl, _a - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -50,146 +50,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -206,22 +211,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -236,19 +243,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -258,21 +266,24 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __LTF: ; A < B - call __FPSTACK_PUSH2 ; Enters B, A - ; ------------- ROM NOS-LESS - ld b, 0Ch ; A > B (Operands stack-reversed) - rst 28h - defb 0Ch; ; A > B - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; Enters B, A + ; ------------- ROM NOS-LESS + ld b, 0Ch ; A > B (Operands stack-reversed) + rst 28h + defb 0Ch; ; A > B + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 27 "strict_bool.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -293,41 +304,46 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 28 "strict_bool.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 29 "strict_bool.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strictbool.asm" ; This routine is called if --strict-boolean was set at the command line. ; It will make any boolean result to be always 0 or 1 + push namespace core __NORMALIZE_BOOLEAN: or a ret z ld a, 1 ret + pop namespace #line 30 "strict_bool.bas" END diff --git a/tests/functional/string_substr.asm b/tests/functional/string_substr.asm index d2465daa9..ec37a7623 100644 --- a/tests/functional/string_substr.asm +++ b/tests/functional/string_substr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl ld a, (_i) @@ -39,16 +39,16 @@ __MAIN_PROGRAM__: ld hl, 65534 push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -197,9 +197,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -207,37 +208,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -247,119 +249,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 39 "string_substr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -379,15 +385,17 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -452,6 +460,7 @@ __STRLEN: ; Direct FASTCALL entry #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -481,6 +490,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -493,159 +503,163 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 19 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 40 "string_substr.bas" END diff --git a/tests/functional/stringfunc.asm b/tests/functional/stringfunc.asm index 788e6e7de..1d51b83d7 100644 --- a/tests/functional/stringfunc.asm +++ b/tests/functional/stringfunc.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _testStr - call __MEM_FREE + call core.__MEM_FREE ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,7 +46,7 @@ _testStr: ld ix, 0 add ix, sp ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR _testStr__leave: ld sp, ix pop ix @@ -183,9 +183,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -193,37 +194,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -233,94 +235,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 36 "stringfunc.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -386,6 +390,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -415,6 +420,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -427,124 +433,128 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 37 "stringfunc.bas" END diff --git a/tests/functional/stringparam.asm b/tests/functional/stringparam.asm index 2dae2deb8..929cbbd63 100644 --- a/tests/functional/stringparam.asm +++ b/tests/functional/stringparam.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _testStr ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,14 +51,14 @@ _testStr: ld l, (ix+4) ld h, (ix+5) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _testStr__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -200,9 +200,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -210,37 +211,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -250,94 +252,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 52 "stringparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -403,6 +407,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -432,6 +437,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -444,125 +450,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 53 "stringparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -574,109 +584,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -684,319 +703,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1051,467 +1090,474 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 54 "stringparam.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 55 "stringparam.bas" END diff --git a/tests/functional/strlocal0.asm b/tests/functional/strlocal0.asm index fd0847a49..8e63a2970 100644 --- a/tests/functional/strlocal0.asm +++ b/tests/functional/strlocal0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,31 +8,31 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -49,18 +49,18 @@ _test: push hl ld de, __LABEL0 ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR ld l, (ix-2) ld h, (ix-1) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _test__leave: ex af, af' exx ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -204,9 +204,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -214,37 +215,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -254,94 +256,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 56 "strlocal0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -353,70 +357,75 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -446,49 +455,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -496,319 +511,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -863,468 +898,475 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 57 "strlocal0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 58 "strlocal0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -1475,90 +1517,92 @@ __PRINT_STR: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -1580,132 +1624,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1730,11 +1779,14 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 59 "strlocal0.bas" END diff --git a/tests/functional/strparam0.asm b/tests/functional/strparam0.asm index 52752b100..ccb46271e 100644 --- a/tests/functional/strparam0.asm +++ b/tests/functional/strparam0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _test1 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -51,14 +51,14 @@ _test2: ld l, (ix+4) ld h, (ix+5) xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _test2__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -74,7 +74,7 @@ _test1: add ix, sp ld l, (ix+4) ld h, (ix+5) - call __LOADSTR + call core.__LOADSTR push hl call _test2 _test1__leave: @@ -82,7 +82,7 @@ _test1__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -230,9 +230,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -240,37 +241,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -280,94 +282,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 82 "strparam0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -433,6 +437,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -462,6 +467,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -474,125 +480,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 83 "strparam0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -604,109 +614,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -714,319 +733,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1081,467 +1120,474 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 84 "strparam0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 85 "strparam0.bas" END diff --git a/tests/functional/strparam1.asm b/tests/functional/strparam1.asm index 4fb578305..16cade29c 100644 --- a/tests/functional/strparam1.asm +++ b/tests/functional/strparam1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,43 +8,43 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) - call __U8TOFREG - call __STR_FAST + call core.__U8TOFREG + call core.__STR_FAST ex de, hl ld hl, __LABEL0 push de - call __ADDSTR + call core.__ADDSTR ex (sp), hl - call __MEM_FREE + call core.__MEM_FREE pop hl push hl call _prnt ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,16 +64,16 @@ _prnt: ld d, h ld e, l ld bc, -2 - call __PSTORE_STR + call core.__PSTORE_STR _prnt__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ld l, (ix-2) ld h, (ix-1) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -216,9 +216,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -226,37 +227,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -266,94 +268,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 67 "strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" ; vim:ts=4:et:sw=4 @@ -436,6 +440,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -465,6 +470,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -537,90 +543,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -642,132 +650,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -792,12 +805,15 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/pstorestr.asm" + push namespace core __PSTORE_STR: push ix pop hl add hl, bc jp __STORE_STR + pop namespace #line 68 "strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/str.asm" ; The STR$( ) BASIC function implementation @@ -808,12 +824,13 @@ __PSTORE_STR: ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -828,22 +845,24 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/str.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -851,257 +870,268 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/str.asm" + push namespace core __STR: __STR_FAST: - PROC - LOCAL __STR_END - LOCAL RECLAIM2 - LOCAL STK_END - ld hl, (STK_END) - push hl; Stores STK_END - ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG - push hl + PROC + LOCAL __STR_END + LOCAL RECLAIM2 + LOCAL STK_END + ld hl, (STK_END) + push hl; Stores STK_END + ld hl, (ATTR_T) ; Saves ATTR_T since it's changed by STR$ due to a ROM BUG + push hl call __FPSTACK_PUSH ; Push number into stack - rst 28h ; # Rom Calculator - defb 2Eh ; # STR$(x) - defb 38h ; # END CALC - call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) - pop hl - ld (ATTR_T), hl ; Restores ATTR_T - pop hl - ld (STK_END), hl ; Balance STK_END to avoid STR$ bug - push bc - push de - inc bc - inc bc - call __MEM_ALLOC ; HL Points to new block - pop de - pop bc - push hl - ld a, h - or l - jr z, __STR_END ; Return if NO MEMORY (NULL) - push bc - push de - ld (hl), c - inc hl - ld (hl), b - inc hl ; Copies length - ex de, hl ; HL = start of original string - ldir ; Copies string content - pop de ; Original (ROM-CALC) string - pop bc ; Original Length + rst 28h ; # Rom Calculator + defb 2Eh ; # STR$(x) + defb 38h ; # END CALC + call __FPSTACK_POP ; Recovers string parameters to A ED CB (Only ED LH are important) + pop hl + ld (ATTR_T), hl ; Restores ATTR_T + pop hl + ld (STK_END), hl ; Balance STK_END to avoid STR$ bug + push bc + push de + inc bc + inc bc + call __MEM_ALLOC ; HL Points to new block + pop de + pop bc + push hl + ld a, h + or l + jr z, __STR_END ; Return if NO MEMORY (NULL) + push bc + push de + ld (hl), c + inc hl + ld (hl), b + inc hl ; Copies length + ex de, hl ; HL = start of original string + ldir ; Copies string content + pop de ; Original (ROM-CALC) string + pop bc ; Original Length __STR_END: - ex de, hl - inc bc - call RECLAIM2 ; Frees TMP Memory - pop hl ; String result - ret + ex de, hl + inc bc + call RECLAIM2 ; Frees TMP Memory + pop hl ; String result + ret RECLAIM2 EQU 19E8h STK_END EQU 5C65h - ENDP + ENDP + pop namespace #line 69 "strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 70 "strparam1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 71 "strparam1.bas" END diff --git a/tests/functional/strparam2.asm b/tests/functional/strparam2.asm index 3be4d5b7b..133efc7db 100644 --- a/tests/functional/strparam2.asm +++ b/tests/functional/strparam2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, _a push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -59,8 +59,8 @@ _test2: ld h, (hl) ld l, c xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _test2__leave: ld sp, ix pop ix @@ -105,70 +105,75 @@ __LABEL0: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -198,49 +203,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -248,319 +259,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -615,426 +646,431 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 69 "strparam2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1161,9 +1197,10 @@ PRINT_EOL_ATTR: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1171,37 +1208,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1211,135 +1249,139 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 70 "strparam2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -1484,90 +1526,92 @@ __PRINT_STR: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -1589,132 +1633,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -1739,5 +1788,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 71 "strparam2.bas" END diff --git a/tests/functional/strparam3.asm b/tests/functional/strparam3.asm index e331d7135..2b79acf29 100644 --- a/tests/functional/strparam3.asm +++ b/tests/functional/strparam3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 - call __LOADSTR + call core.__LOADSTR push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -55,8 +55,8 @@ _test2: ld h, (hl) ld l, c xor a - call __PRINTSTR - call PRINT_EOL_ATTR + call core.__PRINTSTR + call core.PRINT_EOL_ATTR _test2__leave: ld sp, ix pop ix @@ -80,7 +80,7 @@ _test__leave: exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -224,9 +224,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -234,37 +235,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -274,94 +276,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 76 "strparam3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -427,6 +431,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -456,6 +461,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -468,125 +474,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 77 "strparam3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" ; Calls PRINT_EOL and then COPY_ATTR, so saves @@ -598,109 +608,118 @@ __LOADSTR: ; __FASTCALL__ entry ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -708,319 +727,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 + rlca rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -1075,467 +1114,474 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/print_eol_attr.asm" + push namespace core PRINT_EOL_ATTR: - call PRINT_EOL - jp COPY_ATTR + call PRINT_EOL + jp COPY_ATTR + pop namespace #line 78 "strparam3.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 79 "strparam3.bas" END diff --git a/tests/functional/strsigil.asm b/tests/functional/strsigil.asm index 9dc66dcdc..a91189598 100644 --- a/tests/functional/strsigil.asm +++ b/tests/functional/strsigil.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,52 +8,52 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _e3: DEFB 00 _i3: DEFB 00, 00, 00, 00, 00 _character: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_character) push hl ld a, (_i3) ld de, (_i3 + 1) ld bc, (_i3 + 3) - call __FTOU32REG + call core.__FTOU32REG push hl ld a, (_i3) ld de, (_i3 + 1) ld bc, (_i3 + 3) - call __FTOU32REG + call core.__FTOU32REG push hl xor a - call __STRSLICE + call core.__STRSLICE ld a, 1 - call __ASC + call core.__ASC ld (_e3), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -189,9 +189,10 @@ __END_PROGRAM: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -199,37 +200,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -239,193 +241,200 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/asc.asm" + push namespace core __ASC: - PROC - LOCAL __ASC_END - ex af, af' ; Saves free_mem flag - ld a, h - or l - ret z ; NULL? return - ld c, (hl) - inc hl - ld b, (hl) - ld a, b - or c - jr z, __ASC_END ; No length? return - inc hl - ld a, (hl) + PROC + LOCAL __ASC_END + ex af, af' ; Saves free_mem flag + ld a, h + or l + ret z ; NULL? return + ld c, (hl) + inc hl + ld b, (hl) + ld a, b + or c + jr z, __ASC_END ; No length? return + inc hl + ld a, (hl) dec hl __ASC_END: - dec hl - ex af, af' - or a - call nz, __MEM_FREE ; Free memory if needed - ex af, af' ; Recover result - ret - ENDP + dec hl + ex af, af' + or a + call nz, __MEM_FREE ; Free memory if needed + ex af, af' ; Recover result + ret + ENDP + pop namespace #line 34 "strsigil.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -442,11 +451,12 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 35 "strsigil.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -466,15 +476,17 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -539,6 +551,7 @@ __STRLEN: ; Direct FASTCALL entry #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -568,6 +581,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -580,159 +594,163 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 19 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 36 "strsigil.bas" END diff --git a/tests/functional/sub16.asm b/tests/functional/sub16.asm index 7855b400c..6b342126d 100644 --- a/tests/functional/sub16.asm +++ b/tests/functional/sub16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld (_b), hl ld hl, (_a) @@ -47,9 +47,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/sub16a.asm b/tests/functional/sub16a.asm index 1641cd1a4..e1c0acece 100644 --- a/tests/functional/sub16a.asm +++ b/tests/functional/sub16a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a) or a @@ -33,9 +33,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/sub16b.asm b/tests/functional/sub16b.asm index 4b2b1f902..a3d367f37 100644 --- a/tests/functional/sub16b.asm +++ b/tests/functional/sub16b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld de, (_a) or a @@ -41,9 +41,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/sub8.asm b/tests/functional/sub8.asm index 098ddbfb2..d0a83d998 100644 --- a/tests/functional/sub8.asm +++ b/tests/functional/sub8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -43,9 +43,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/sub8a.asm b/tests/functional/sub8a.asm index bb85f1d3d..1e99590ab 100644 --- a/tests/functional/sub8a.asm +++ b/tests/functional/sub8a.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) sub h @@ -31,9 +31,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/sub8b.asm b/tests/functional/sub8b.asm index 8a50dd668..ab8df17f2 100644 --- a/tests/functional/sub8b.asm +++ b/tests/functional/sub8b.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld hl, (_a - 1) sub h @@ -37,9 +37,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/subf00.asm b/tests/functional/subf00.asm index 4e628495d..08904b511 100644 --- a/tests/functional/subf00.asm +++ b/tests/functional/subf00.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 80h DEFB 00h @@ -30,22 +30,22 @@ _b: DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _b + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 082h ld de, 00000h ld bc, 00000h - call __SUBF + call core.__SUBF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,6 +60,7 @@ __END_PROGRAM: ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -80,45 +81,49 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 25 "subf00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 26 "subf00.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -133,19 +138,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -155,13 +161,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __SUBF: ; Subtraction - call __FPSTACK_PUSH2 ; ENTERS B, A - ; ------------- ROM SUB - rst 28h - defb 01h ; EXCHANGE - defb 03h ; SUB - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; ENTERS B, A + ; ------------- ROM SUB + rst 28h + defb 01h ; EXCHANGE + defb 03h ; SUB + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 27 "subf00.bas" END diff --git a/tests/functional/subf01.asm b/tests/functional/subf01.asm index 40c152a64..c064aed89 100644 --- a/tests/functional/subf01.asm +++ b/tests/functional/subf01.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 80h DEFB 00h @@ -30,8 +30,8 @@ _b: DEFB 00h DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_b) ld de, (_b + 1) ld bc, (_b + 3) @@ -41,15 +41,15 @@ __MAIN_PROGRAM__: push hl ld h, 082h push hl - call __SUBF + call core.__SUBF ld hl, _b - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,43 +60,46 @@ __END_PROGRAM: ret ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 29 "subf01.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -111,19 +114,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/subf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -133,13 +137,15 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __SUBF: ; Subtraction - call __FPSTACK_PUSH2 ; ENTERS B, A - ; ------------- ROM SUB - rst 28h - defb 01h ; EXCHANGE - defb 03h ; SUB - defb 38h; ; END CALC - jp __FPSTACK_POP + call __FPSTACK_PUSH2 ; ENTERS B, A + ; ------------- ROM SUB + rst 28h + defb 01h ; EXCHANGE + defb 03h ; SUB + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace #line 30 "subf01.bas" END diff --git a/tests/functional/subf16c.asm b/tests/functional/subf16c.asm index a0b1e9078..c262272ca 100644 --- a/tests/functional/subf16c.asm +++ b/tests/functional/subf16c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 00h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __SUB32 + call core.__SWAP32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,15 +57,15 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,31 +80,34 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 45 "subf16c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -114,6 +117,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 46 "subf16c.bas" END diff --git a/tests/functional/subi32c.asm b/tests/functional/subi32c.asm index f4b151fa2..17b789a64 100644 --- a/tests/functional/subi32c.asm +++ b/tests/functional/subi32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __SUB32 + call core.__SWAP32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -66,15 +66,15 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -89,31 +89,34 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 54 "subi32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -123,6 +126,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 55 "subi32c.bas" END diff --git a/tests/functional/subparam.asm b/tests/functional/subparam.asm index 0470381fb..492f4856d 100644 --- a/tests/functional/subparam.asm +++ b/tests/functional/subparam.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 87 push af ld a, 127 @@ -28,9 +28,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/subrec.asm b/tests/functional/subrec.asm index ceba1e5c3..3e6863407 100644 --- a/tests/functional/subrec.asm +++ b/tests/functional/subrec.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _result: DEFB 01h DEFB 00h @@ -31,9 +31,9 @@ _result: DEFB 00h _x: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: - call CLS +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: + call core.CLS ld a, 1 ld (_x), a jp __LABEL0 @@ -52,16 +52,16 @@ __LABEL3: call _fact ld hl, __LABEL5 xor a - call __PRINTSTR + call core.__PRINTSTR ld a, (_x) - call __PRINTU8 + call core.__PRINTU8 ld hl, __LABEL6 xor a - call __PRINTSTR + call core.__PRINTSTR ld hl, (_result) ld de, (_result + 2) - call __PRINTU32 - call PRINT_EOL + call core.__PRINTU32 + call core.PRINT_EOL __LABEL4: ld hl, _x inc (hl) @@ -74,9 +74,9 @@ __LABEL2: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -97,7 +97,7 @@ _fact: push hl ld de, 0 ld hl, 2 - call __SUB32 + call core.__SUB32 jp c, _fact__leave __LABEL8: ld l, (ix+4) @@ -108,7 +108,7 @@ __LABEL8: push hl ld de, (_result + 2) ld hl, (_result) - call __MUL32 + call core.__MUL32 ld (_result), hl ld (_result + 2), de ld l, (ix+4) @@ -119,7 +119,7 @@ __LABEL8: push hl ld de, 0 ld hl, 1 - call __SUB32 + call core.__SUB32 push de push hl call _fact @@ -154,60 +154,64 @@ __LABEL6: ; Our faster implementation #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 116 "subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/_mul32.asm" @@ -215,75 +219,80 @@ __CLS_SCR: ; Used with permission. ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') ; 64bit result is returned in H'L'H L B'C'A C + push namespace core __MUL32_64START: - push hl - exx - ld b, h - ld c, l ; BC = Low Part (A) - pop hl ; HL = Load Part (B) - ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') - push hl - exx - pop bc ; B'C' = HightPart(A) - exx ; A = B'C'BC , B = D'E'DE - ; multiply routine 32 * 32bit = 64bit - ; h'l'hlb'c'ac = b'c'bc * d'e'de - ; needs register a, changes flags - ; - ; this routine was with tiny differences in the - ; sinclair zx81 rom for the mantissa multiply + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply __LMUL: - and a ; reset carry flag - sbc hl,hl ; result bits 32..47 = 0 - exx - sbc hl,hl ; result bits 48..63 = 0 - exx - ld a,b ; mpr is b'c'ac - ld b,33 ; initialize loop counter - jp __LMULSTART + and a ; reset carry flag + sbc hl,hl ; result bits 32..47 = 0 + exx + sbc hl,hl ; result bits 48..63 = 0 + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART __LMULLOOP: - jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP - ; it can save up to 33 * 2 = 66 cycles - ; But JR if 3 cycles faster if JUMP not taken! - add hl,de ; result += mpd - exx - adc hl,de - exx + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx __LMULNOADD: - exx - rr h ; right shift upper - rr l ; 32bit of result - exx - rr h - rr l + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l __LMULSTART: - exx - rr b ; right shift mpr/ - rr c ; lower 32bit of result - exx - rra ; equivalent to rr a - rr c - djnz __LMULLOOP - ret ; result in h'l'hlb'c'ac + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/mul32.asm" -__MUL32: ; multiplies 32 bit un/signed integer. - ; First operand stored in DEHL, and 2nd onto stack - ; Lowest part of 2nd operand on top of the stack - ; returns the result in DE.HL - exx - pop hl ; Return ADDRESS - pop de ; Low part - ex (sp), hl ; CALLEE -> HL = High part - ex de, hl - call __MUL32_64START + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) - exx - push bc - exx - pop de - ld h, a - ld l, c - ret + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace #line 117 "subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; vim:ts=4:sw=4:et: @@ -294,6 +303,7 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -323,49 +333,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -373,319 +389,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -740,422 +776,425 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 118 "subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -1282,9 +1321,10 @@ __PRINT_TABLE: ; Jump table for 0 .. 22 codes ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1292,37 +1332,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1332,421 +1373,437 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/printstr.asm" ; PRINT command routine ; Prints string pointed by HL + push namespace core PRINT_STR: __PRINTSTR: ; __FASTCALL__ Entry to print_string - PROC - LOCAL __PRINT_STR_LOOP - LOCAL __PRINT_STR_END - ld d, a ; Saves A reg (Flag) for later - ld a, h - or l - ret z ; Return if the pointer is NULL - push hl - ld c, (hl) - inc hl - ld b, (hl) - inc hl ; BC = LEN(a$); HL = &a$ + PROC + LOCAL __PRINT_STR_LOOP + LOCAL __PRINT_STR_END + ld d, a ; Saves A reg (Flag) for later + ld a, h + or l + ret z ; Return if the pointer is NULL + push hl + ld c, (hl) + inc hl + ld b, (hl) + inc hl ; BC = LEN(a$); HL = &a$ __PRINT_STR_LOOP: - ld a, b - or c - jr z, __PRINT_STR_END ; END if BC (counter = 0) - ld a, (hl) - call __PRINTCHAR - inc hl - dec bc - jp __PRINT_STR_LOOP + ld a, b + or c + jr z, __PRINT_STR_END ; END if BC (counter = 0) + ld a, (hl) + call __PRINTCHAR + inc hl + dec bc + jp __PRINT_STR_LOOP __PRINT_STR_END: - pop hl - ld a, d ; Recovers A flag - or a ; If not 0 this is a temporary string. Free it - ret z - jp __MEM_FREE ; Frees str from heap and return from there + pop hl + ld a, d ; Recovers A flag + or a ; If not 0 this is a temporary string. Free it + ret z + jp __MEM_FREE ; Frees str from heap and return from there __PRINT_STR: - ; Fastcall Entry - ; It ONLY prints strings - ; HL = String start - ; BC = String length (Number of chars) - push hl ; Push str address for later - ld d, a ; Saves a FLAG - jp __PRINT_STR_LOOP - ENDP + ; Fastcall Entry + ; It ONLY prints strings + ; HL = String start + ; BC = String length (Number of chars) + push hl ; Push str address for later + ld d, a ; Saves a FLAG + jp __PRINT_STR_LOOP + ENDP + pop namespace #line 119 "subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/printi32.asm" + push namespace core __PRINTI32: - ld a, d - or a - jp p, __PRINTU32 - call __PRINT_MINUS - call __NEG32 + ld a, d + or a + jp p, __PRINTU32 + call __PRINT_MINUS + call __NEG32 __PRINTU32: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - ld a, h - or l - or d - or e - jp z, __PRINTU_START - push bc - ld bc, 0 - push bc - ld bc, 10 - push bc ; Push 00 0A (10 Dec) into the stack = divisor - call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) - pop bc - exx - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - exx - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + or d + or e + jp z, __PRINTU_START + push bc + ld bc, 0 + push bc + ld bc, 10 + push bc ; Push 00 0A (10 Dec) into the stack = divisor + call __DIVU32 ; Divides by 32. D'E'H'L' contains modulo (L' since < 10) + pop bc + exx + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + exx + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu32.asm" #line 120 "subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div8.asm" - ; -------------------------------- + ; -------------------------------- + push namespace core __DIVU8: ; 8 bit unsigned integer division - ; Divides (Top of stack, High Byte) / A - pop hl ; -------------------------------- - ex (sp), hl ; CALLEE + ; Divides (Top of stack, High Byte) / A + pop hl ; -------------------------------- + ex (sp), hl ; CALLEE __DIVU8_FAST: ; Does A / H - ld l, h - ld h, a ; At this point do H / L - ld b, 8 - xor a ; A = 0, Carry Flag = 0 + ld l, h + ld h, a ; At this point do H / L + ld b, 8 + xor a ; A = 0, Carry Flag = 0 __DIV8LOOP: - sla h - rla - cp l - jr c, __DIV8NOSUB - sub l - inc h + sla h + rla + cp l + jr c, __DIV8NOSUB + sub l + inc h __DIV8NOSUB: - djnz __DIV8LOOP - ld l, a ; save remainder - ld a, h ; - ret ; a = Quotient, - ; -------------------------------- + djnz __DIV8LOOP + ld l, a ; save remainder + ld a, h ; + ret ; a = Quotient, + ; -------------------------------- __DIVI8: ; 8 bit signed integer division Divides (Top of stack) / A - pop hl ; -------------------------------- - ex (sp), hl + pop hl ; -------------------------------- + ex (sp), hl __DIVI8_FAST: - ld e, a ; store operands for later - ld c, h - or a ; negative? - jp p, __DIV8A - neg ; Make it positive + ld e, a ; store operands for later + ld c, h + or a ; negative? + jp p, __DIV8A + neg ; Make it positive __DIV8A: - ex af, af' - ld a, h - or a - jp p, __DIV8B - neg - ld h, a ; make it positive + ex af, af' + ld a, h + or a + jp p, __DIV8B + neg + ld h, a ; make it positive __DIV8B: - ex af, af' - call __DIVU8_FAST - ld a, c - xor l ; bit 7 of A = 1 if result is negative - ld a, h ; Quotient - ret p ; return if positive - neg - ret + ex af, af' + call __DIVU8_FAST + ld a, c + xor l ; bit 7 of A = 1 if result is negative + ld a, h ; Quotient + ret p ; return if positive + neg + ret __MODU8: ; 8 bit module. REturns A mod (Top of stack) (unsigned operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODU8_FAST: ; __FASTCALL__ entry - call __DIVU8_FAST - ld a, l ; Remainder - ret ; a = Modulus + call __DIVU8_FAST + ld a, l ; Remainder + ret ; a = Modulus __MODI8: ; 8 bit module. REturns A mod (Top of stack) (For singed operands) - pop hl - ex (sp), hl ; CALLEE + pop hl + ex (sp), hl ; CALLEE __MODI8_FAST: ; __FASTCALL__ entry - call __DIVI8_FAST - ld a, l ; remainder - ret ; a = Modulus + call __DIVI8_FAST + ld a, l ; remainder + ret ; a = Modulus + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi8.asm" + push namespace core __PRINTI8: ; Prints an 8 bits number in Accumulator (A) - ; Converts 8 to 32 bits - or a - jp p, __PRINTU8 - push af - call __PRINT_MINUS - pop af - neg + ; Converts 8 to 32 bits + or a + jp p, __PRINTU8 + push af + call __PRINT_MINUS + pop af + neg __PRINTU8: - PROC - LOCAL __PRINTU_LOOP - ld b, 0 ; Counter + PROC + LOCAL __PRINTU_LOOP + ld b, 0 ; Counter __PRINTU_LOOP: - or a - jp z, __PRINTU_START - push bc - ld h, 10 - call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) - pop bc - ld a, l - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - ld a, h - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + or a + jp z, __PRINTU_START + push bc + ld h, 10 + call __DIVU8_FAST ; Divides by 10. D'E'H'L' contains modulo (L' since < 10) + pop bc + ld a, l + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + ld a, h + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu8.asm" #line 121 "subrec.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/sub32.asm" @@ -1754,24 +1811,26 @@ __PRINTU_LOOP: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 122 "subrec.bas" END diff --git a/tests/functional/substr_empty.asm b/tests/functional/substr_empty.asm index d3dfe9e9d..a90777e2a 100644 --- a/tests/functional/substr_empty.asm +++ b/tests/functional/substr_empty.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, (_b) ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -122,6 +122,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -151,6 +152,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -276,9 +278,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -286,37 +289,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -329,90 +333,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -482,94 +488,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -591,132 +599,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -741,5 +754,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 20 "substr_empty.bas" END diff --git a/tests/functional/substr_empty2.asm b/tests/functional/substr_empty2.asm index b58a5f7ce..ff516be05 100644 --- a/tests/functional/substr_empty2.asm +++ b/tests/functional/substr_empty2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -128,6 +128,7 @@ __LABEL0: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -157,6 +158,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -282,9 +284,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -292,37 +295,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -335,90 +339,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -488,94 +494,96 @@ __MEM_SUBTRACT: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 72 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -597,132 +605,137 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -747,5 +760,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 28 "substr_empty2.bas" END diff --git a/tests/functional/substr_expr.asm b/tests/functional/substr_expr.asm index 9725410ff..ed245d9b2 100644 --- a/tests/functional/substr_expr.asm +++ b/tests/functional/substr_expr.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,46 +8,46 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, (_a) - call __ADDSTR + call core.__ADDSTR push hl ld hl, 5 push hl ld hl, 65534 push hl ld a, 1 - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _b - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -191,9 +191,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -201,37 +202,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -241,119 +243,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 33 "substr_expr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -419,6 +425,7 @@ __STORE_STR2: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -448,6 +455,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -460,198 +468,204 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 34 "substr_expr.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -667,74 +681,76 @@ __STRCATEND: ; it in dynamic memory if needed). Returns pointer (HL) to resulting ; string. NULL (0) if no memory for padding. ; + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 35 "substr_expr.bas" END diff --git a/tests/functional/substr_expr2.asm b/tests/functional/substr_expr2.asm index 4332fff1c..3e5b5736a 100644 --- a/tests/functional/substr_expr2.asm +++ b/tests/functional/substr_expr2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,27 +8,27 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00 _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 push hl ld hl, (_i) @@ -40,16 +40,16 @@ __MAIN_PROGRAM__: add hl, de push hl xor a - call __STRSLICE + call core.__STRSLICE ex de, hl ld hl, _a - call __STORE_STR2 + call core.__STORE_STR2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -198,9 +198,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -208,37 +209,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -248,119 +250,123 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/storestr2.asm" + push namespace core __PISTORE_STR2: ; Indirect store temporary string at (IX + BC) push ix pop hl add hl, bc __ISTORE_STR2: - ld c, (hl) ; Dereferences HL - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string variable address) + ld c, (hl) ; Dereferences HL + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string variable address) __STORE_STR2: - push hl - ld c, (hl) - inc hl - ld h, (hl) - ld l, c ; HL = *HL (real string address) - push de - call __MEM_FREE - pop de - pop hl - ld (hl), e - inc hl - ld (hl), d - dec hl ; HL points to mem address variable. This might be useful in the future. - ret + push hl + ld c, (hl) + inc hl + ld h, (hl) + ld l, c ; HL = *HL (real string address) + push de + call __MEM_FREE + pop de + pop hl + ld (hl), e + inc hl + ld (hl), d + dec hl ; HL points to mem address variable. This might be useful in the future. + ret + pop namespace #line 40 "substr_expr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" ; String slicing library @@ -380,15 +386,17 @@ __STORE_STR2: ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -453,6 +461,7 @@ __STRLEN: ; Direct FASTCALL entry #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -482,6 +491,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -494,159 +504,163 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 19 "/zxbasic/src/arch/zx48k/library-asm/strslice.asm" + push namespace core __STRSLICE: ; Callee entry - pop hl ; Return ADDRESS - pop bc ; Last char pos - pop de ; 1st char pos - ex (sp), hl ; CALLEE. -> String start + pop hl ; Return ADDRESS + pop bc ; Last char pos + pop de ; 1st char pos + ex (sp), hl ; CALLEE. -> String start __STRSLICE_FAST: ; __FASTCALL__ Entry - PROC - LOCAL __CONT - LOCAL __EMPTY - LOCAL __FREE_ON_EXIT - push hl ; Stores original HL pointer to be recovered on exit - ex af, af' ; Saves A register for later - push hl - call __STRLEN - inc bc ; Last character position + 1 (string starts from 0) - or a - sbc hl, bc ; Compares length with last char position - jr nc, __CONT ; If Carry => We must copy to end of string - add hl, bc ; Restore back original LEN(a$) in HL - ld b, h - ld c, l ; Copy to the end of str - ccf ; Clears Carry flag for next subtraction + PROC + LOCAL __CONT + LOCAL __EMPTY + LOCAL __FREE_ON_EXIT + push hl ; Stores original HL pointer to be recovered on exit + ex af, af' ; Saves A register for later + push hl + call __STRLEN + inc bc ; Last character position + 1 (string starts from 0) + or a + sbc hl, bc ; Compares length with last char position + jr nc, __CONT ; If Carry => We must copy to end of string + add hl, bc ; Restore back original LEN(a$) in HL + ld b, h + ld c, l ; Copy to the end of str + ccf ; Clears Carry flag for next subtraction __CONT: - ld h, b - ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) - sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy - jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) - jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) - ld b, h - ld c, l ; BC = Number of chars to copy - inc bc - inc bc ; +2 bytes for string length number - push bc - push de - call __MEM_ALLOC - pop de - pop bc - ld a, h - or l - jr z, __EMPTY ; Return if NULL (no memory) - dec bc - dec bc ; Number of chars to copy (Len of slice) - ld (hl), c - inc hl - ld (hl), b - inc hl ; Stores new string length - ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack - inc hl - inc hl ; Skip string length - add hl, de ; Were to start from A$ - pop de ; Start of new string chars - push de ; Stores it again - ldir ; Copies BC chars - pop de - dec de - dec de ; Points to String LEN start - ex de, hl ; Returns it in HL - jr __FREE_ON_EXIT + ld h, b + ld l, c ; HL = Last char position to copy (1 for char 0, 2 for char 1, etc) + sbc hl, de ; HL = LEN(a$) - DE => Number of chars to copy + jr z, __EMPTY ; 0 Chars to copy => Return HL = 0 (NULL STR) + jr c, __EMPTY ; If Carry => Nothing to return (NULL STR) + ld b, h + ld c, l ; BC = Number of chars to copy + inc bc + inc bc ; +2 bytes for string length number + push bc + push de + call __MEM_ALLOC + pop de + pop bc + ld a, h + or l + jr z, __EMPTY ; Return if NULL (no memory) + dec bc + dec bc ; Number of chars to copy (Len of slice) + ld (hl), c + inc hl + ld (hl), b + inc hl ; Stores new string length + ex (sp), hl ; Pointer to A$ now in HL; Pointer to new string chars in Stack + inc hl + inc hl ; Skip string length + add hl, de ; Were to start from A$ + pop de ; Start of new string chars + push de ; Stores it again + ldir ; Copies BC chars + pop de + dec de + dec de ; Points to String LEN start + ex de, hl ; Returns it in HL + jr __FREE_ON_EXIT __EMPTY: ; Return NULL (empty) string - pop hl - ld hl, 0 ; Return NULL + pop hl + ld hl, 0 ; Return NULL __FREE_ON_EXIT: - ex af, af' ; Recover original A register - ex (sp), hl ; Original HL pointer - or a - call nz, __MEM_FREE - pop hl ; Recover result - ret - ENDP + ex af, af' ; Recover original A register + ex (sp), hl ; Original HL pointer + or a + call nz, __MEM_FREE + pop hl ; Recover result + ret + ENDP + pop namespace #line 41 "substr_expr2.bas" END diff --git a/tests/functional/substrlval.asm b/tests/functional/substrlval.asm index 0e326abdf..35a6a1bfe 100644 --- a/tests/functional/substrlval.asm +++ b/tests/functional/substrlval.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR __LABEL__30: ld hl, __LABEL1 push hl @@ -41,13 +41,13 @@ __LABEL__30: ld hl, 3 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -202,9 +202,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -212,37 +213,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -252,204 +254,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 44 "substrlval.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -526,6 +532,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -555,6 +562,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -627,90 +635,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -732,132 +742,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -882,5 +897,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 45 "substrlval.bas" END diff --git a/tests/functional/subu32c.asm b/tests/functional/subu32c.asm index d26cf859e..b726f9270 100644 --- a/tests/functional/subu32c.asm +++ b/tests/functional/subu32c.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _level: DEFB 01h DEFB 00h @@ -30,16 +30,16 @@ _le: DEFB 00h _l: DEFB 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_level) ld de, (_level + 2) push de push hl ld de, (_le + 2) ld hl, (_le) - call __SWAP32 - call __SUB32 + call core.__SWAP32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_le + 2) @@ -48,7 +48,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_le) @@ -57,7 +57,7 @@ __MAIN_PROGRAM__: push hl ld hl, (_level) ld de, (_level + 2) - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, (_level) @@ -66,15 +66,15 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __SUB32 + call core.__SUB32 ld (_l), hl ld (_l + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -89,31 +89,34 @@ __END_PROGRAM: ; Perform TOP of the stack - DEHL ; Pops operand out of the stack (CALLEE) ; and returns result in DEHL. Carry an Z are set correctly + push namespace core __SUB32: - exx - pop bc ; saves return address in BC' - exx - or a ; clears carry flag - ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC - ld c, l - pop hl - sbc hl, bc - ex de, hl - ld b, h ; High part (DE) now in HL. Repeat operation - ld c, l - pop hl - sbc hl, bc - ex de, hl ; DEHL now has de 32 bit result - exx - push bc ; puts return address back - exx - ret + exx + pop bc ; saves return address in BC' + exx + or a ; clears carry flag + ld b, h ; Operands come reversed => BC <- HL, HL = HL - BC + ld c, l + pop hl + sbc hl, bc + ex de, hl + ld b, h ; High part (DE) now in HL. Repeat operation + ld c, l + pop hl + sbc hl, bc + ex de, hl ; DEHL now has de 32 bit result + exx + push bc ; puts return address back + exx + ret + pop namespace #line 54 "subu32c.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -123,6 +126,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 55 "subu32c.bas" END diff --git a/tests/functional/swap32.asm b/tests/functional/swap32.asm index 0ed64fbaf..17a7804d2 100644 --- a/tests/functional/swap32.asm +++ b/tests/functional/swap32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,39 +8,39 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 0FFh DEFB 0FFh DEFB 00h DEFB 00h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 10 - call __SWAP32 - call __DIVU32 + call core.__SWAP32 + call core.__DIVU32 ld (_a), hl ld (_a + 2), de ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -52,145 +52,150 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/div32.asm" - ; --------------------------------------------------------- + ; --------------------------------------------------------- + push namespace core __DIVU32: ; 32 bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor - ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q - ; - ; Changes A, BC DE HL B'C' D'E' H'L' - ; --------------------------------------------------------- - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; OPERANDS P = Dividend, Q = Divisor => OPERATION => P / Q + ; + ; Changes A, BC DE HL B'C' D'E' H'L' + ; --------------------------------------------------------- + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVU32START: ; Performs D'E'H'L' / HLDE - ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) - push de ; push Lowpart(Q) - ex de, hl ; DE = HL - ld hl, 0 - exx - ld b, h - ld c, l - pop hl - push de - ex de, hl - ld hl, 0 ; H'L'HL = 0 - exx - pop bc ; Pop HightPart(B) => B = B'C'BC - exx - ld a, 32 ; Loop count + ; Now switch to DIVIDEND = B'C'BC / DIVISOR = D'E'DE (A / B) + push de ; push Lowpart(Q) + ex de, hl ; DE = HL + ld hl, 0 + exx + ld b, h + ld c, l + pop hl + push de + ex de, hl + ld hl, 0 ; H'L'HL = 0 + exx + pop bc ; Pop HightPart(B) => B = B'C'BC + exx + ld a, 32 ; Loop count __DIV32LOOP: - sll c ; B'C'BC << 1 ; Output most left bit to carry - rl b - exx - rl c - rl b - exx - adc hl, hl - exx - adc hl, hl - exx - sbc hl,de - exx - sbc hl,de - exx - jp nc, __DIV32NOADD ; use JP inside a loop for being faster - add hl, de - exx - adc hl, de - exx - dec bc + sll c ; B'C'BC << 1 ; Output most left bit to carry + rl b + exx + rl c + rl b + exx + adc hl, hl + exx + adc hl, hl + exx + sbc hl,de + exx + sbc hl,de + exx + jp nc, __DIV32NOADD ; use JP inside a loop for being faster + add hl, de + exx + adc hl, de + exx + dec bc __DIV32NOADD: - dec a - jp nz, __DIV32LOOP ; use JP inside a loop for being faster - ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL - push hl - exx - pop de - ex de, hl ; D'E'H'L' = 32 bits modulus - push bc - exx - pop de ; DE = B'C' - ld h, b - ld l, c ; DEHL = quotient D'E'H'L' = Modulus - ret ; DEHL = quotient, D'E'H'L' = Modulus + dec a + jp nz, __DIV32LOOP ; use JP inside a loop for being faster + ; At this point, quotient is stored in B'C'BC and the reminder in H'L'HL + push hl + exx + pop de + ex de, hl ; D'E'H'L' = 32 bits modulus + push bc + exx + pop de ; DE = B'C' + ld h, b + ld l, c ; DEHL = quotient D'E'H'L' = Modulus + ret ; DEHL = quotient, D'E'H'L' = Modulus __MODU32: ; 32 bit modulus for 32bit unsigned division - ; DEHL = Dividend, Stack Top = Divisor (DE, HL) - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVU32START ; At return, modulus is at D'E'H'L' + ; DEHL = Dividend, Stack Top = Divisor (DE, HL) + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVU32START ; At return, modulus is at D'E'H'L' __MODU32START: - exx - push de - push hl - exx - pop hl - pop de - ret + exx + push de + push hl + exx + pop hl + pop de + ret __DIVI32: ; 32 bit signed division - ; DEHL = Dividend, Stack Top = Divisor - ; A = Dividend, B = Divisor => A / B - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + ; DEHL = Dividend, Stack Top = Divisor + ; A = Dividend, B = Divisor => A / B + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend __DIVI32START: - exx - ld a, d ; Save sign - ex af, af' - bit 7, d ; Negative? - call nz, __NEG32 ; Negates DEHL - exx ; Now works with H'L'D'E' - ex af, af' - xor h - ex af, af' ; Stores sign of the result for later - bit 7, h ; Negative? - ex de, hl ; HLDE = DEHL - call nz, __NEG32 - ex de, hl - call __DIVU32START - ex af, af' ; Recovers sign - and 128 ; positive? - ret z - jp __NEG32 ; Negates DEHL and returns from there + exx + ld a, d ; Save sign + ex af, af' + bit 7, d ; Negative? + call nz, __NEG32 ; Negates DEHL + exx ; Now works with H'L'D'E' + ex af, af' + xor h + ex af, af' ; Stores sign of the result for later + bit 7, h ; Negative? + ex de, hl ; HLDE = DEHL + call nz, __NEG32 + ex de, hl + call __DIVU32START + ex af, af' ; Recovers sign + and 128 ; positive? + ret z + jp __NEG32 ; Negates DEHL and returns from there __MODI32: ; 32bits signed division modulus - exx - pop hl ; return address - pop de ; low part - ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend - call __DIVI32START - jp __MODU32START + exx + pop hl ; return address + pop de ; low part + ex (sp), hl ; CALLEE Convention ; H'L'D'E' => Dividend + call __DIVI32START + jp __MODU32START + pop namespace #line 27 "swap32.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/swap32.asm" ; Exchanges current DE HL with the ; ones in the stack + push namespace core __SWAP32: - pop bc ; Return address + pop bc ; Return address ex (sp), hl inc sp inc sp @@ -200,6 +205,7 @@ __SWAP32: dec sp dec sp push bc - ret + ret + pop namespace #line 28 "swap32.bas" END diff --git a/tests/functional/sys_letarrsubstr0.asm b/tests/functional/sys_letarrsubstr0.asm index 1bbb4aca7..37e81722f 100644 --- a/tests/functional/sys_letarrsubstr0.asm +++ b/tests/functional/sys_letarrsubstr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFW __LABEL2 _a.__DATA__.__PTR__: @@ -37,11 +37,11 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 2 - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -51,13 +51,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 2) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -210,9 +210,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -220,37 +221,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -260,204 +262,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "sys_letarrsubstr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -534,6 +540,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -563,6 +570,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -635,90 +643,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -740,132 +750,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -890,5 +905,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "sys_letarrsubstr0.bas" END diff --git a/tests/functional/sys_letarrsubstr1.asm b/tests/functional/sys_letarrsubstr1.asm index 4b33eb3d6..3e9eb4536 100644 --- a/tests/functional/sys_letarrsubstr1.asm +++ b/tests/functional/sys_letarrsubstr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a: @@ -39,14 +39,14 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 2 - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, _c - call __STORE_STR + call core.__STORE_STR ld hl, (_c) push hl xor a @@ -56,13 +56,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 2) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -215,9 +215,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -225,37 +226,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -265,204 +267,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 43 "sys_letarrsubstr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -539,6 +545,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -568,6 +575,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -640,90 +648,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -745,132 +755,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -895,5 +910,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 44 "sys_letarrsubstr1.bas" END diff --git a/tests/functional/sys_letarrsubstr2.asm b/tests/functional/sys_letarrsubstr2.asm index c093c1638..886e5f412 100644 --- a/tests/functional/sys_letarrsubstr2.asm +++ b/tests/functional/sys_letarrsubstr2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,21 +8,21 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a: @@ -39,17 +39,17 @@ _a.__DATA__: __LABEL2: DEFW 0000h DEFB 02h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a.__DATA__ + 2 - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, _c - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, (_c) - call __ADDSTR + call core.__ADDSTR push hl ld a, 1 push af @@ -58,13 +58,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a.__DATA__ + 2) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -217,9 +217,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -227,37 +228,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -267,204 +269,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 45 "sys_letarrsubstr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -541,6 +547,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -570,6 +577,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -642,90 +650,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -747,132 +757,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -897,114 +912,119 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 46 "sys_letarrsubstr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 47 "sys_letarrsubstr2.bas" END diff --git a/tests/functional/sys_letsubstr0.asm b/tests/functional/sys_letsubstr0.asm index f82254940..0375017f4 100644 --- a/tests/functional/sys_letsubstr0.asm +++ b/tests/functional/sys_letsubstr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld hl, __LABEL1 push hl xor a @@ -39,13 +39,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -198,9 +198,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -208,37 +209,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -248,204 +250,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 40 "sys_letsubstr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -522,6 +528,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -551,6 +558,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -623,90 +631,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -728,132 +738,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -878,5 +893,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 41 "sys_letsubstr0.bas" END diff --git a/tests/functional/sys_letsubstr1.asm b/tests/functional/sys_letsubstr1.asm index e0f624040..6df26bf4b 100644 --- a/tests/functional/sys_letsubstr1.asm +++ b/tests/functional/sys_letsubstr1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, _c - call __STORE_STR + call core.__STORE_STR ld hl, (_c) push hl xor a @@ -44,13 +44,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -203,9 +203,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -213,37 +214,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -253,204 +255,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 43 "sys_letsubstr1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -527,6 +533,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -556,6 +563,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -628,90 +636,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -733,132 +743,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -883,5 +898,6 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 44 "sys_letsubstr1.bas" END diff --git a/tests/functional/sys_letsubstr2.asm b/tests/functional/sys_letsubstr2.asm index ead59162c..8cc5c6bf6 100644 --- a/tests/functional/sys_letsubstr2.asm +++ b/tests/functional/sys_letsubstr2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,36 +8,36 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _a - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, _c - call __STORE_STR + call core.__STORE_STR ld de, __LABEL1 ld hl, (_c) - call __ADDSTR + call core.__ADDSTR push hl ld a, 1 push af @@ -46,13 +46,13 @@ __MAIN_PROGRAM__: ld hl, 1 push hl ld hl, (_a) - call __LETSUBSTR + call core.__LETSUBSTR ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -205,9 +205,10 @@ __LABEL1: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -215,37 +216,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -255,204 +257,208 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/letsubstr.asm" + push namespace core __LETSUBSTR: - PROC - LOCAL __CONT0 - LOCAL __CONT1 - LOCAL __CONT2 - LOCAL __FREE_STR - exx - pop hl ; Return address - pop de ; p1 - pop bc ; p0 - exx - pop af ; Flag - ex af, af' ; Save it for later - pop de ; B$ - exx - push hl ; push ret addr back - exx - push de ; B$ addr to be freed upon return (if A != 0) - ld a, h - or l - jp z, __FREE_STR ; Return if null - ld c, (hl) - inc hl - ld b, (hl) ; BC = Str length - inc hl ; HL = String start - push bc - exx - ex de, hl - or a - sbc hl, bc ; HL = Length of string requested by user - inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 - ex de, hl ; Saves it in DE - pop hl ; HL = String length - exx - jp c, __FREE_STR ; Return if p0 > p1 - exx - or a - sbc hl, bc ; P0 >= String length? - exx - jp z, __FREE_STR ; Return if equal - jp c, __FREE_STR ; Return if greater - exx - add hl, bc ; Add it back - sbc hl, de ; Length of substring > string => Truncate it - add hl, de ; add it back - jr nc, __CONT0 ; Length of substring within a$ - ld d, h - ld e, l ; Truncate length of substring to fit within the strlen + PROC + LOCAL __CONT0 + LOCAL __CONT1 + LOCAL __CONT2 + LOCAL __FREE_STR + exx + pop hl ; Return address + pop de ; p1 + pop bc ; p0 + exx + pop af ; Flag + ex af, af' ; Save it for later + pop de ; B$ + exx + push hl ; push ret addr back + exx + push de ; B$ addr to be freed upon return (if A != 0) + ld a, h + or l + jp z, __FREE_STR ; Return if null + ld c, (hl) + inc hl + ld b, (hl) ; BC = Str length + inc hl ; HL = String start + push bc + exx + ex de, hl + or a + sbc hl, bc ; HL = Length of string requested by user + inc hl ; len (a$(p0 TO p1)) = p1 - p0 + 1 + ex de, hl ; Saves it in DE + pop hl ; HL = String length + exx + jp c, __FREE_STR ; Return if p0 > p1 + exx + or a + sbc hl, bc ; P0 >= String length? + exx + jp z, __FREE_STR ; Return if equal + jp c, __FREE_STR ; Return if greater + exx + add hl, bc ; Add it back + sbc hl, de ; Length of substring > string => Truncate it + add hl, de ; add it back + jr nc, __CONT0 ; Length of substring within a$ + ld d, h + ld e, l ; Truncate length of substring to fit within the strlen __CONT0: ; At this point DE = Length of substring to copy - ; BC = start of char to copy - push de - push bc - exx - pop bc - add hl, bc ; Start address (within a$) so copy from b$ (in DE) - push hl - exx - pop hl ; Start address (within a$) so copy from b$ (in DE) - ld b, d ; Length of string - ld c, e - ld (hl), ' ' - ld d, h - ld e, l - inc de - dec bc - ld a, b - or c - jr z, __CONT2 - ; At this point HL = DE = Start of Write zone in a$ - ; BC = Number of chars to write - ldir + ; BC = start of char to copy + push de + push bc + exx + pop bc + add hl, bc ; Start address (within a$) so copy from b$ (in DE) + push hl + exx + pop hl ; Start address (within a$) so copy from b$ (in DE) + ld b, d ; Length of string + ld c, e + ld (hl), ' ' + ld d, h + ld e, l + inc de + dec bc + ld a, b + or c + jr z, __CONT2 + ; At this point HL = DE = Start of Write zone in a$ + ; BC = Number of chars to write + ldir __CONT2: - pop bc ; Recovers Length of string to copy - exx - ex de, hl ; HL = Source, DE = Target - ld a, h - or l - jp z, __FREE_STR ; Return if B$ is NULL - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jp z, __FREE_STR ; Return if len(b$) = 0 - ; Now if len(b$) < len(char to copy), copy only len(b$) chars - push de - push hl - push bc - exx - pop hl ; LEN (b$) - or a - sbc hl, bc - add hl, bc - jr nc, __CONT1 - ; If len(b$) < len(to copy) - ld b, h ; BC = len(to copy) - ld c, l + pop bc ; Recovers Length of string to copy + exx + ex de, hl ; HL = Source, DE = Target + ld a, h + or l + jp z, __FREE_STR ; Return if B$ is NULL + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jp z, __FREE_STR ; Return if len(b$) = 0 + ; Now if len(b$) < len(char to copy), copy only len(b$) chars + push de + push hl + push bc + exx + pop hl ; LEN (b$) + or a + sbc hl, bc + add hl, bc + jr nc, __CONT1 + ; If len(b$) < len(to copy) + ld b, h ; BC = len(to copy) + ld c, l __CONT1: - pop hl - pop de - ldir ; Copy b$ into a$(x to y) + pop hl + pop de + ldir ; Copy b$ into a$(x to y) __FREE_STR: pop hl - ex af, af' - or a ; If not 0, free - jp nz, __MEM_FREE - ret - ENDP + ex af, af' + or a ; If not 0, free + jp nz, __MEM_FREE + ret + ENDP + pop namespace #line 45 "sys_letsubstr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -529,6 +535,7 @@ __FREE_STR: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -558,6 +565,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; vim: ts=4:et:sw=4: @@ -630,90 +638,92 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 71 "/zxbasic/src/arch/zx48k/library-asm/realloc.asm" ; --------------------------------------------------------------------- ; MEM_REALLOC @@ -735,132 +745,137 @@ __MEM_SUBTRACT: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -885,114 +900,119 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 46 "sys_letsubstr2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 47 "sys_letsubstr2.bas" END diff --git a/tests/functional/ubound0.asm b/tests/functional/ubound0.asm index 89cb7b5be..2b0bbe75f 100644 --- a/tests/functional/ubound0.asm +++ b/tests/functional/ubound0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -38,16 +38,16 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ubound1.asm b/tests/functional/ubound1.asm index 89cb7b5be..2b0bbe75f 100644 --- a/tests/functional/ubound1.asm +++ b/tests/functional/ubound1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _a: @@ -38,16 +38,16 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 2 ld (_b), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ubound10.asm b/tests/functional/ubound10.asm index 7ecd7ef70..efbc6fcb7 100644 --- a/tests/functional/ubound10.asm +++ b/tests/functional/ubound10.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test3 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,7 +56,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -97,7 +97,7 @@ _test3: ld hl, -8 ld de, __LABEL5 ld bc, 9 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS push ix pop hl ld de, -8 @@ -109,7 +109,7 @@ _test3__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -194,6 +194,7 @@ _test3.a.__UBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -223,6 +224,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -288,9 +290,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -298,37 +301,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -341,90 +345,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -438,25 +444,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -471,6 +479,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -577,7 +586,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 92 "ubound10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -591,6 +601,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -651,6 +662,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 93 "ubound10.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -720,94 +732,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 94 "ubound10.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/ubound11.asm b/tests/functional/ubound11.asm index a4fc0b91e..5d6860677 100644 --- a/tests/functional/ubound11.asm +++ b/tests/functional/ubound11.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test3 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -72,7 +72,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -113,7 +113,7 @@ _test3: ld hl, -8 ld de, __LABEL5 ld bc, 9 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS push ix pop hl ld de, -8 @@ -125,7 +125,7 @@ _test3__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -210,6 +210,7 @@ _test3.a.__UBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -239,6 +240,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -304,9 +306,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -314,37 +317,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -357,90 +361,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -454,25 +460,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -487,6 +495,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -593,7 +602,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 108 "ubound11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -607,6 +617,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -667,6 +678,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 109 "ubound11.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -736,94 +748,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 110 "ubound11.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/ubound12.asm b/tests/functional/ubound12.asm index 5e0d5a291..f2e163e48 100644 --- a/tests/functional/ubound12.asm +++ b/tests/functional/ubound12.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test1 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,7 +56,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -97,7 +97,7 @@ _test1: ld hl, -8 ld de, __LABEL5 ld bc, 18 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS push ix pop hl ld de, -8 @@ -111,7 +111,7 @@ _test1__leave: push hl ld l, (ix-6) ld h, (ix-5) - call __ARRAYSTR_FREE_MEM + call core.__ARRAYSTR_FREE_MEM ex af, af' exx ld sp, ix @@ -212,6 +212,7 @@ _test2__leave: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -241,6 +242,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -306,9 +308,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -316,37 +319,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -359,90 +363,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -456,25 +462,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -489,6 +497,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -595,7 +604,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 110 "ubound12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" ; This routine is in charge of freeing an array of strings from memory @@ -669,134 +679,138 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 6 "/zxbasic/src/arch/zx48k/library-asm/arraystrfree.asm" + push namespace core __ARRAYSTR_FREE: - PROC - LOCAL __ARRAY_LOOP - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl + PROC + LOCAL __ARRAY_LOOP + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl __ARRAYSTR_FREE_FAST: ; Fastcall entry: DE = Number of elements - ld a, h - or l - ret z ; ret if NULL - ld b, d - ld c, e + ld a, h + or l + ret z ; ret if NULL + ld b, d + ld c, e __ARRAY_LOOP: - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = (HL) = String Pointer - push hl - push bc - ex de, hl - call __MEM_FREE ; Frees it from memory - pop bc - pop hl - dec bc - ld a, b - or c - jp nz, __ARRAY_LOOP - ret ; Frees it and return - ENDP + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = (HL) = String Pointer + push hl + push bc + ex de, hl + call __MEM_FREE ; Frees it from memory + pop bc + pop hl + dec bc + ld a, b + or c + jp nz, __ARRAY_LOOP + ret ; Frees it and return + ENDP __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself - ex de, hl - pop hl ; (ret address) - ex (sp), hl ; Callee -> HL = Number of elements - ex de, hl - push hl ; Saves array pointer for later - call __ARRAYSTR_FREE_FAST - pop hl ; recovers array block pointer - jp __MEM_FREE ; Frees it and returns from __MEM_FREE + ex de, hl + pop hl ; (ret address) + ex (sp), hl ; Callee -> HL = Number of elements + ex de, hl + push hl ; Saves array pointer for later + call __ARRAYSTR_FREE_FAST + pop hl ; recovers array block pointer + jp __MEM_FREE ; Frees it and returns from __MEM_FREE + pop namespace #line 111 "ubound12.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -810,6 +824,7 @@ __ARRAYSTR_FREE_MEM: ; like the above, buf also frees the array itself ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -870,6 +885,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 112 "ubound12.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/ubound2.asm b/tests/functional/ubound2.asm index 2bddb16a4..4e4386274 100644 --- a/tests/functional/ubound2.asm +++ b/tests/functional/ubound2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00h DEFB 00h @@ -46,19 +46,19 @@ __LABEL0: _a.__UBOUND__: DEFW 0005h DEFW 0009h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,6 +80,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -140,5 +141,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 22 "ubound2.bas" END diff --git a/tests/functional/ubound3.asm b/tests/functional/ubound3.asm index 71d2ec0ec..ba4243b11 100644 --- a/tests/functional/ubound3.asm +++ b/tests/functional/ubound3.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 _a: @@ -38,16 +38,16 @@ __LABEL0: DEFW 0001h DEFW 0003h DEFB 01h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 5 ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/ubound4.asm b/tests/functional/ubound4.asm index f71e47ff5..9084fd7fa 100644 --- a/tests/functional/ubound4.asm +++ b/tests/functional/ubound4.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 01h DEFB 00h @@ -46,19 +46,19 @@ __LABEL0: _a.__UBOUND__: DEFW 0005h DEFW 0009h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,6 +80,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -140,5 +141,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 22 "ubound4.bas" END diff --git a/tests/functional/ubound5.asm b/tests/functional/ubound5.asm index 4330a9588..f85fd3f9b 100644 --- a/tests/functional/ubound5.asm +++ b/tests/functional/ubound5.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 02h DEFB 00h @@ -46,19 +46,19 @@ __LABEL0: _a.__UBOUND__: DEFW 0005h DEFW 0009h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -80,6 +80,7 @@ __END_PROGRAM: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -140,5 +141,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 22 "ubound5.bas" END diff --git a/tests/functional/ubound6.asm b/tests/functional/ubound6.asm index 7d94e0f43..27f7dcad7 100644 --- a/tests/functional/ubound6.asm +++ b/tests/functional/ubound6.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,34 +8,34 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -64,7 +64,7 @@ _test: ld hl, -8 ld de, __LABEL5 ld bc, 9 - call __ALLOC_LOCAL_ARRAY_WITH_BOUNDS + call core.__ALLOC_LOCAL_ARRAY_WITH_BOUNDS ld hl, 0 ld (_b), hl jp __LABEL0 @@ -75,7 +75,7 @@ __LABEL3: pop hl ld de, -8 add hl, de - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -93,7 +93,7 @@ _test__leave: exx ld l, (ix-6) ld h, (ix-5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -178,6 +178,7 @@ _test.a.__UBOUND__: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -207,6 +208,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -272,9 +274,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -282,37 +285,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -325,90 +329,92 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/calloc.asm" ; --------------------------------------------------------------------- ; MEM_CALLOC @@ -422,25 +428,27 @@ __MEM_SUBTRACT: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core __MEM_CALLOC: - push bc - call __MEM_ALLOC - pop bc - ld a, h - or l - ret z ; No memory - ld (hl), 0 - dec bc - ld a, b - or c - ret z ; Already filled (1 byte-length block) - ld d, h - ld e, l - inc de - push hl - ldir - pop hl - ret + push bc + call __MEM_ALLOC + pop bc + ld a, h + or l + ret z ; No memory + ld (hl), 0 + dec bc + ld a, b + or c + ret z ; Already filled (1 byte-length block) + ld d, h + ld e, l + inc de + push hl + ldir + pop hl + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" ; --------------------------------------------------------------------- ; __ALLOC_LOCAL_ARRAY @@ -455,6 +463,7 @@ __MEM_CALLOC: ; Returns: ; HL = (IX + HL) + 4 ; --------------------------------------------------------------------- + push namespace core __ALLOC_LOCAL_ARRAY: push de push ix @@ -561,7 +570,8 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: exx call __ALLOC_INITIALIZED_LOCAL_ARRAY jp __ALLOC_LOCAL_ARRAY_WITH_BOUNDS2 -#line 137 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" +#line 139 "/zxbasic/src/arch/zx48k/library-asm/arrayalloc.asm" + pop namespace #line 76 "ubound6.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bound.asm" ; --------------------------------------------------------- @@ -575,6 +585,7 @@ __ALLOC_INITIALIZED_LOCAL_ARRAY_WITH_BOUNDS: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -635,6 +646,7 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 77 "ubound6.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; vim: ts=4:et:sw=4: @@ -704,94 +716,96 @@ __DIM_NOT_EXIST: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 78 "ubound6.bas" __LABEL5: DEFB 01h diff --git a/tests/functional/ubound7.asm b/tests/functional/ubound7.asm index 563c7ea1a..1028d8f73 100644 --- a/tests/functional/ubound7.asm +++ b/tests/functional/ubound7.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -45,22 +45,22 @@ __LABEL5: _a.__UBOUND__: DEFW 0005h DEFW 0009h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _test ld hl, (_b) push hl ld hl, _a - call __UBOUND + call core.__UBOUND ld (_c), hl ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -81,7 +81,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -115,6 +115,7 @@ _test__leave: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -175,5 +176,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 58 "ubound7.bas" END diff --git a/tests/functional/ubound8.asm b/tests/functional/ubound8.asm index 178ada0a2..814efde1a 100644 --- a/tests/functional/ubound8.asm +++ b/tests/functional/ubound8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -45,17 +45,17 @@ __LABEL5: _a.__UBOUND__: DEFW 0005h DEFW 0009h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -76,7 +76,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -110,6 +110,7 @@ _test__leave: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -170,5 +171,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 53 "ubound8.bas" END diff --git a/tests/functional/ubound9.asm b/tests/functional/ubound9.asm index 2c12b6447..153557a27 100644 --- a/tests/functional/ubound9.asm +++ b/tests/functional/ubound9.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,16 +8,16 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _b: DEFB 00, 00 _c: @@ -45,17 +45,17 @@ __LABEL5: _a.__UBOUND__: DEFW 0005h DEFW 0009h -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, _a push hl call _test2 ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -92,7 +92,7 @@ __LABEL3: push hl ld l, (ix+4) ld h, (ix+5) - call __UBOUND + call core.__UBOUND ld (_c), hl __LABEL4: ld hl, (_b) @@ -126,6 +126,7 @@ _test1__leave: ; Parameters: ; HL = PTR to array ; [stack - 2] -> N (dimension) + push namespace core PROC LOCAL __BOUND LOCAL __DIM_NOT_EXIST @@ -186,5 +187,6 @@ __DIM_NOT_EXIST: ld hl, 0 ret ENDP + pop namespace #line 69 "ubound9.bas" END diff --git a/tests/functional/ubyteopt.asm b/tests/functional/ubyteopt.asm index d13b13236..d0d4183dc 100644 --- a/tests/functional/ubyteopt.asm +++ b/tests/functional/ubyteopt.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, 2 push af ld a, 1 @@ -28,9 +28,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/use_zxnext_asm.asm b/tests/functional/use_zxnext_asm.asm index d38c40721..4bf03f3ec 100644 --- a/tests/functional/use_zxnext_asm.asm +++ b/tests/functional/use_zxnext_asm.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,18 +8,18 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: #line 3 "use_zxnext_asm.bas" LDIX LDWS @@ -54,9 +54,9 @@ __MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/usr0.asm b/tests/functional/usr0.asm index eae5ea8f2..293e69e8a 100644 --- a/tests/functional/usr0.asm +++ b/tests/functional/usr0.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,35 +8,35 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - call __PRINT_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + call core.__PRINT_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, __LABEL0 xor a - call USR_STR - call __PRINTU16 - call PRINT_EOL + call core.USR_STR + call core.__PRINTU16 + call core.PRINT_EOL ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -56,70 +56,75 @@ __LABEL0: ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that #line 1 "/zxbasic/src/arch/zx48k/library-asm/sposn.asm" ; Printing positioning library. - PROC - LOCAL ECHO_E + push namespace core + PROC + LOCAL ECHO_E __LOAD_S_POSN: ; Loads into DE current ROW, COL print position from S_POSN mem var. - ld de, (S_POSN) - ld hl, (MAXX) - or a - sbc hl, de - ex de, hl - ret + ld de, (S_POSN) + ld hl, (MAXX) + or a + sbc hl, de + ex de, hl + ret __SAVE_S_POSN: ; Saves ROW, COL from DE into S_POSN mem var. - ld hl, (MAXX) - or a - sbc hl, de - ld (S_POSN), hl ; saves it again - ret + ld hl, (MAXX) + or a + sbc hl, de + ld (S_POSN), hl ; saves it again + ret ECHO_E EQU 23682 MAXX EQU ECHO_E ; Max X position + 1 MAXY EQU MAXX + 1 ; Max Y position + 1 S_POSN EQU 23688 POSX EQU S_POSN ; Current POS X POSY EQU S_POSN + 1 ; Current POS Y - ENDP + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/cls.asm" ; JUMPS directly to spectrum CLS ; This routine does not clear lower screen ;CLS EQU 0DAFh ; Our faster implementation + push namespace core CLS: - PROC - LOCAL COORDS - LOCAL __CLS_SCR - LOCAL ATTR_P - LOCAL SCREEN - ld hl, 0 - ld (COORDS), hl + PROC + LOCAL COORDS + LOCAL __CLS_SCR + LOCAL ATTR_P + LOCAL SCREEN + ld hl, 0 + ld (COORDS), hl ld hl, 1821h - ld (S_POSN), hl + ld (S_POSN), hl __CLS_SCR: - ld hl, SCREEN - ld (hl), 0 - ld d, h - ld e, l - inc de - ld bc, 6144 - ldir - ; Now clear attributes - ld a, (ATTR_P) - ld (hl), a - ld bc, 767 - ldir - ret + ld hl, SCREEN + ld (hl), 0 + ld d, h + ld e, l + inc de + ld bc, 6144 + ldir + ; Now clear attributes + ld a, (ATTR_P) + ld (hl), a + ld bc, 767 + ldir + ret COORDS EQU 23677 SCREEN EQU 16384 ; Default start of the screen (can be changed) ATTR_P EQU 23693 ;you can poke (SCREEN_SCRADDR) to change CLS, DRAW & PRINTing address SCREEN_ADDR EQU (__CLS_SCR + 1) ; Address used by print and other screen routines - ; to get the start of the screen - ENDP + ; to get the start of the screen + ENDP + pop namespace #line 8 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -149,49 +154,55 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/in_screen.asm" + push namespace core __IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits (MAXX, MAXY) - PROC - LOCAL __IN_SCREEN_ERR - ld hl, MAXX - ld a, e - cp (hl) - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - inc hl - cp (hl) - ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ;; ret + ; Returns NO carry if current coords (D, E) + ; are OUT of the screen limits (MAXX, MAXY) + PROC + LOCAL __IN_SCREEN_ERR + ld hl, MAXX + ld a, e + cp (hl) + jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ld a, d + inc hl + cp (hl) + ;; jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range + ;; ret ret c ; Return if carry (OK) __IN_SCREEN_ERR: __OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen + ; Jumps here if out of screen + ld a, ERROR_OutOfScreen jp __STOP ; Saves error code and exits - ENDP + ENDP + pop namespace #line 9 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/table_jump.asm" + push namespace core JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a + add a, a JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - ld e, a - ld d, 0 + ld e, a + ld d, 0 JUMP_HL_PLUS_DE: ; Does JP (HL + DE) - add hl, de - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl + add hl, de + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl CALL_HL: - jp (hl) + jp (hl) + pop namespace #line 10 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" ; Sets ink color in ATTR_P permanently ; Parameter: Paper color in A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/const.asm" ; Global constants + push namespace core P_FLAG EQU 23697 FLAGS2 EQU 23681 ATTR_P EQU 23693 ; permanet ATTRIBUTES @@ -199,319 +210,339 @@ CALL_HL: CHARS EQU 23606 ; Pointer to ROM/RAM Charset UDG EQU 23675 ; Pointer to UDG Charset MEM0 EQU 5C92h ; Temporary memory buffer used by ROM chars + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/ink.asm" + push namespace core INK: - PROC - LOCAL __SET_INK - LOCAL __SET_INK2 - ld de, ATTR_P + PROC + LOCAL __SET_INK + LOCAL __SET_INK2 + ld de, ATTR_P __SET_INK: - cp 8 - jr nz, __SET_INK2 - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - or 7 ; Set bits 0,1,2 to enable transparency - ld (de), a - ret + cp 8 + jr nz, __SET_INK2 + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + or 7 ; Set bits 0,1,2 to enable transparency + ld (de), a + ret __SET_INK2: - ; Another entry. This will set the ink color at location pointer by DE - and 7 ; # Gets color mod 8 - ld b, a ; Saves the color - ld a, (de) - and 0F8h ; Clears previous value - or b - ld (de), a - inc de ; Points DE to MASK_T or MASK_P - ld a, (de) - and 0F8h ; Reset bits 0,1,2 sign to disable transparency - ld (de), a ; Store new attr - ret + ; Another entry. This will set the ink color at location pointer by DE + and 7 ; # Gets color mod 8 + ld b, a ; Saves the color + ld a, (de) + and 0F8h ; Clears previous value + or b + ld (de), a + inc de ; Points DE to MASK_T or MASK_P + ld a, (de) + and 0F8h ; Reset bits 0,1,2 sign to disable transparency + ld (de), a ; Store new attr + ret ; Sets the INK color passed in A register in the ATTR_T variable INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP + ld de, ATTR_T + jp __SET_INK + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/paper.asm" ; Sets paper color in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core PAPER: - PROC - LOCAL __SET_PAPER - LOCAL __SET_PAPER2 - ld de, ATTR_P + PROC + LOCAL __SET_PAPER + LOCAL __SET_PAPER2 + ld de, ATTR_P __SET_PAPER: - cp 8 - jr nz, __SET_PAPER2 - inc de - ld a, (de) - or 038h - ld (de), a - ret - ; Another entry. This will set the paper color at location pointer by DE + cp 8 + jr nz, __SET_PAPER2 + inc de + ld a, (de) + or 038h + ld (de), a + ret + ; Another entry. This will set the paper color at location pointer by DE __SET_PAPER2: - and 7 ; # Remove - rlca - rlca - rlca ; a *= 8 - ld b, a ; Saves the color - ld a, (de) - and 0C7h ; Clears previous value - or b - ld (de), a - inc de ; Points to MASK_T or MASK_P accordingly - ld a, (de) - and 0C7h ; Resets bits 3,4,5 - ld (de), a - ret + and 7 ; # Remove + rlca + rlca + rlca ; a *= 8 + ld b, a ; Saves the color + ld a, (de) + and 0C7h ; Clears previous value + or b + ld (de), a + inc de ; Points to MASK_T or MASK_P accordingly + ld a, (de) + and 0C7h ; Resets bits 3,4,5 + ld (de), a + ret ; Sets the PAPER color passed in A register in the ATTR_T variable PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP + ld de, ATTR_T + jp __SET_PAPER + ENDP + pop namespace #line 12 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/flash.asm" ; Sets flash flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core FLASH: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_FLASH: - ; Another entry. This will set the flash flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x80 + ; Another entry. This will set the flash flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x80 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 07Fh ; Clears previous value - or b - ld (hl), a - inc hl - res 7, (hl) ;Reset bit 7 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 07Fh ; Clears previous value + or b + ld (hl), a + inc hl + res 7, (hl) ;Reset bit 7 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 7, (hl) ;Set bit 7 to enable transparency - ret + inc hl ; Points DE to MASK_T or MASK_P + set 7, (hl) ;Set bit 7 to enable transparency + ret ; Sets the FLASH flag passed in A register in the ATTR_T variable FLASH_TMP: - ld hl, ATTR_T - jr __SET_FLASH + ld hl, ATTR_T + jr __SET_FLASH ENDP + pop namespace #line 13 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bright.asm" ; Sets bright flag in ATTR_P permanently ; Parameter: Paper color in A register + push namespace core BRIGHT: - ld hl, ATTR_P + ld hl, ATTR_P PROC LOCAL IS_TR LOCAL IS_ZERO __SET_BRIGHT: - ; Another entry. This will set the bright flag at location pointer by DE - cp 8 - jr z, IS_TR - ; # Convert to 0/1 - or a - jr z, IS_ZERO - ld a, 0x40 + ; Another entry. This will set the bright flag at location pointer by DE + cp 8 + jr z, IS_TR + ; # Convert to 0/1 + or a + jr z, IS_ZERO + ld a, 0x40 IS_ZERO: - ld b, a ; Saves the color - ld a, (hl) - and 0BFh ; Clears previous value - or b - ld (hl), a - inc hl - res 6, (hl) ;Reset bit 6 to disable transparency - ret + ld b, a ; Saves the color + ld a, (hl) + and 0BFh ; Clears previous value + or b + ld (hl), a + inc hl + res 6, (hl) ;Reset bit 6 to disable transparency + ret IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P + inc hl ; Points DE to MASK_T or MASK_P set 6, (hl) ;Set bit 6 to enable transparency - ret + ret ; Sets the BRIGHT flag passed in A register in the ATTR_T variable BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT + ld hl, ATTR_T + jr __SET_BRIGHT ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/over.asm" ; Sets OVER flag in P_FLAG permanently ; Parameter: OVER flag in bit 0 of A register #line 1 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" #line 4 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + push namespace core COPY_ATTR: - ; Just copies current permanent attribs to temporal attribs - ; and sets print mode - PROC - LOCAL INVERSE1 - LOCAL __REFRESH_TMP + ; Just copies current permanent attribs into temporal attribs + ; and sets print mode + PROC + LOCAL INVERSE1 + LOCAL __REFRESH_TMP INVERSE1 EQU 02Fh - ld hl, (ATTR_P) - ld (ATTR_T), hl - ld hl, FLAGS2 - call __REFRESH_TMP - ld hl, P_FLAG - call __REFRESH_TMP + ld hl, (ATTR_P) + ld (ATTR_T), hl + ld hl, FLAGS2 + call __REFRESH_TMP + ld hl, P_FLAG + call __REFRESH_TMP __SET_ATTR_MODE: ; Another entry to set print modes. A contains (P_FLAG) - LOCAL TABLE - LOCAL CONT2 - rra ; Over bit to carry - ld a, (FLAGS2) - rla ; Over bit in bit 1, Over2 bit in bit 2 - and 3 ; Only bit 0 and 1 (OVER flag) - ld c, a - ld b, 0 - ld hl, TABLE - add hl, bc - ld a, (hl) - ld (PRINT_MODE), a - ld hl, (P_FLAG) - xor a ; NOP -> INVERSE0 - bit 2, l - jr z, CONT2 - ld a, INVERSE1 ; CPL -> INVERSE1 + LOCAL TABLE + LOCAL CONT2 + rra ; Over bit to carry + ld a, (FLAGS2) + rla ; Over bit in bit 1, Over2 bit in bit 2 + and 3 ; Only bit 0 and 1 (OVER flag) + ld c, a + ld b, 0 + ld hl, TABLE + add hl, bc + ld a, (hl) + ld (PRINT_MODE), a + ld hl, (P_FLAG) + xor a ; NOP -> INVERSE0 + bit 2, l + jr z, CONT2 + ld a, INVERSE1 ; CPL -> INVERSE1 CONT2: - ld (INVERSE_MODE), a - ret + ld (INVERSE_MODE), a + ret TABLE: - nop ; NORMAL MODE - xor (hl) ; OVER 1 MODE - and (hl) ; OVER 2 MODE - or (hl) ; OVER 3 MODE -#line 65 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" + nop ; NORMAL MODE + xor (hl) ; OVER 1 MODE + and (hl) ; OVER 2 MODE + or (hl) ; OVER 3 MODE +#line 67 "/zxbasic/src/arch/zx48k/library-asm/copy_attr.asm" __REFRESH_TMP: - ld a, (hl) - and 10101010b - ld c, a - rra - or c - ld (hl), a - ret - ENDP + ld a, (hl) + and 10101010b + ld c, a + rra + or c + ld (hl), a + ret + ENDP + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/over.asm" + push namespace core OVER: - PROC - ld c, a ; saves it for later - and 2 - ld hl, FLAGS2 - res 1, (HL) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 ; # Convert to 0/1 - add a, a; # Shift left 1 bit for permanent - ld hl, P_FLAG - res 1, (hl) - or (hl) - ld (hl), a - ret + PROC + ld c, a ; saves it for later + and 2 + ld hl, FLAGS2 + res 1, (HL) + or (hl) + ld (hl), a + ld a, c ; Recovers previous value + and 1 ; # Convert to 0/1 + add a, a; # Shift left 1 bit for permanent + ld hl, P_FLAG + res 1, (hl) + or (hl) + ld (hl), a + ret ; Sets OVER flag in P_FLAG temporarily OVER_TMP: - ld c, a ; saves it for later - and 2 ; gets bit 1; clears carry - rra - ld hl, FLAGS2 - res 0, (hl) - or (hl) - ld (hl), a - ld a, c ; Recovers previous value - and 1 - ld hl, P_FLAG - res 0, (hl) + ld c, a ; saves it for later + and 2 ; gets bit 1; clears carry + rra + ld hl, FLAGS2 + res 0, (hl) or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + ld (hl), a + ld a, c ; Recovers previous value + and 1 + ld hl, P_FLAG + res 0, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 15 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/inverse.asm" ; Sets INVERSE flag in P_FLAG permanently ; Parameter: INVERSE flag in bit 0 of A register + push namespace core INVERSE: - PROC - and 1 ; # Convert to 0/1 - add a, a; # Shift left 3 bits for permanent - add a, a - add a, a - ld hl, P_FLAG - res 3, (hl) - or (hl) - ld (hl), a - ret + PROC + and 1 ; # Convert to 0/1 + add a, a; # Shift left 3 bits for permanent + add a, a + add a, a + ld hl, P_FLAG + res 3, (hl) + or (hl) + ld (hl), a + ret ; Sets INVERSE flag in P_FLAG temporarily INVERSE_TMP: - and 1 - add a, a - add a, a; # Shift left 2 bits for temporary - ld hl, P_FLAG - res 2, (hl) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP + and 1 + add a, a + add a, a; # Shift left 2 bits for temporary + ld hl, P_FLAG + res 2, (hl) + or (hl) + ld (hl), a + jp __SET_ATTR_MODE + ENDP + pop namespace #line 16 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/bold.asm" ; Sets BOLD flag in P_FLAG permanently ; Parameter: BOLD flag in bit 0 of A register + push namespace core BOLD: - PROC - and 1 - rlca + PROC + and 1 rlca rlca - ld hl, FLAGS2 - res 3, (HL) - or (hl) - ld (hl), a - ret + rlca + ld hl, FLAGS2 + res 3, (HL) + or (hl) + ld (hl), a + ret ; Sets BOLD flag in P_FLAG temporarily BOLD_TMP: - and 1 - rlca - rlca - ld hl, FLAGS2 - res 2, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rlca + rlca + ld hl, FLAGS2 + res 2, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 17 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/italic.asm" ; Sets ITALIC flag in P_FLAG permanently ; Parameter: ITALIC flag in bit 0 of A register + push namespace core ITALIC: - PROC - and 1 + PROC + and 1 rrca rrca rrca - ld hl, FLAGS2 - res 5, (HL) - or (hl) - ld (hl), a - ret + ld hl, FLAGS2 + res 5, (HL) + or (hl) + ld (hl), a + ret ; Sets ITALIC flag in P_FLAG temporarily ITALIC_TMP: - and 1 - rrca - rrca - rrca - rrca - ld hl, FLAGS2 - res 4, (hl) - or (hl) - ld (hl), a - ret - ENDP + and 1 + rrca + rrca + rrca + rrca + ld hl, FLAGS2 + res 4, (hl) + or (hl) + ld (hl), a + ret + ENDP + pop namespace #line 18 "/zxbasic/src/arch/zx48k/library-asm/print.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/attr.asm" ; Attribute routines ; vim:ts=4:et:sw: + push namespace core __ATTR_ADDR: ; calc start address in DE (as (32 * d) + e) ; Contributed by Santiago Romero at http://www.speccy.org @@ -566,469 +597,477 @@ SET_PIXEL_ADDR_ATTR: ld de, (SCREEN_ADDR) add hl, de ;; Final screen addr jp __SET_ATTR2 + pop namespace #line 20 "/zxbasic/src/arch/zx48k/library-asm/print.asm" ; Putting a comment starting with @INIT
; will make the compiler to add a CALL to
; It is useful for initialization routines. + push namespace core __PRINT_INIT: ; To be called before program starts (initializes library) - PROC - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - ld hl, 1821h - ld (MAXX), hl ; Sets current maxX and maxY - xor a - ld (FLAGS2), a - ret + PROC + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + ld hl, 1821h + ld (MAXX), hl ; Sets current maxX and maxY + xor a + ld (FLAGS2), a + ret __PRINTCHAR: ; Print character store in accumulator (A register) - ; Modifies H'L', B'C', A'F', D'E', A - LOCAL PO_GR_1 - LOCAL __PRCHAR - LOCAL __PRINT_CONT - LOCAL __PRINT_CONT2 - LOCAL __PRINT_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - LOCAL __ROM_SCROLL_SCR - LOCAL __TVFLAGS - __ROM_SCROLL_SCR EQU 0DFEh - __TVFLAGS EQU 5C3Ch + ; Modifies H'L', B'C', A'F', D'E', A + LOCAL PO_GR_1 + LOCAL __PRCHAR + LOCAL __PRINT_CONT + LOCAL __PRINT_CONT2 + LOCAL __PRINT_JUMP + LOCAL __SRCADDR + LOCAL __PRINT_UDG + LOCAL __PRGRAPH + LOCAL __PRINT_START + LOCAL __ROM_SCROLL_SCR + LOCAL __TVFLAGS + __ROM_SCROLL_SCR EQU 0DFEh + __TVFLAGS EQU 5C3Ch PRINT_JUMP_STATE EQU __PRINT_JUMP + 1 __PRINT_JUMP: - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively - LOCAL __SCROLL + jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively + LOCAL __SCROLL __SCROLL: ; Scroll? - ld hl, __TVFLAGS - bit 1, (hl) - ret z - call __ROM_SCROLL_SCR - ld hl, __TVFLAGS - res 1, (hl) - ret -#line 76 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, __TVFLAGS + bit 1, (hl) + ret z + call __ROM_SCROLL_SCR + ld hl, __TVFLAGS + res 1, (hl) + ret +#line 78 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_START: - cp ' ' - jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones - exx ; Switch to alternative registers - ex af, af' ; Saves a value (char to print) for later - call __SCROLL -#line 87 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + cp ' ' + jp c, __PRINT_SPECIAL ; Characters below ' ' are special ones + exx ; Switch to alternative registers + ex af, af' ; Saves a value (char to print) for later + call __SCROLL +#line 89 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN ; At this point we have the new coord - ld hl, (SCREEN_ADDR) - ld a, d - ld c, a ; Saves it for later - and 0F8h ; Masks 3 lower bit ; zy - ld d, a - ld a, c ; Recovers it - and 07h ; MOD 7 ; y1 - rrca - rrca - rrca - or e - ld e, a - add hl, de ; HL = Screen address + DE - ex de, hl ; DE = Screen address - ex af, af' - cp 80h ; Is it an UDG or a ? - jp c, __SRCADDR - cp 90h - jp nc, __PRINT_UDG - ; Print a 8 bit pattern (80h to 8Fh) - ld b, a - call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 - ld hl, MEM0 - jp __PRGRAPH + ld hl, (SCREEN_ADDR) + ld a, d + ld c, a ; Saves it for later + and 0F8h ; Masks 3 lower bit ; zy + ld d, a + ld a, c ; Recovers it + and 07h ; MOD 7 ; y1 + rrca + rrca + rrca + or e + ld e, a + add hl, de ; HL = Screen address + DE + ex de, hl ; DE = Screen address + ex af, af' + cp 80h ; Is it an UDG or a ? + jp c, __SRCADDR + cp 90h + jp nc, __PRINT_UDG + ; Print a 8 bit pattern (80h to 8Fh) + ld b, a + call PO_GR_1 ; This ROM routine will generate the bit pattern at MEM0 + ld hl, MEM0 + jp __PRGRAPH PO_GR_1 EQU 0B38h __PRINT_UDG: - sub 90h ; Sub ASC code - ld bc, (UDG) - jp __PRGRAPH0 + sub 90h ; Sub ASC code + ld bc, (UDG) + jp __PRGRAPH0 __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source __SRCADDR: - ld bc, (CHARS) + ld bc, (CHARS) __PRGRAPH0: - add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org - ld l, a - ld h, 0 ; HL = a * 2 (accumulator) - add hl, hl - add hl, hl ; HL = a * 8 - add hl, bc ; HL = CHARS address + add a, a ; A = a * 2 (since a < 80h) ; Thanks to Metalbrain at http://foro.speccy.org + ld l, a + ld h, 0 ; HL = a * 2 (accumulator) + add hl, hl + add hl, hl ; HL = a * 8 + add hl, bc ; HL = CHARS address __PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD - bit 4, (iy + $47) - call nz, __ITALIC - ld b, 8 ; 8 bytes per char + ex de, hl ; HL = Write Address, DE = CHARS address + bit 2, (iy + $47) + call nz, __BOLD + bit 4, (iy + $47) + call nz, __ITALIC + ld b, 8 ; 8 bytes per char __PRCHAR: - ld a, (de) ; DE *must* be ALWAYS source, and HL destiny + ld a, (de) ; DE *must* be ALWAYS source, and HL destiny PRINT_MODE: ; Which operation is used to write on the screen - ; Set it with: - ; LD A, - ; LD (PRINT_MODE), A - ; - ; Available opertions: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; + ; Set it with: + ; LD A, + ; LD (PRINT_MODE), A + ; + ; Available opertions: + ; NORMAL : 0h --> NOP ; OVER 0 + ; XOR : AEh --> XOR (HL) ; OVER 1 + ; OR : B6h --> OR (HL) ; PUTSPRITE + ; AND : A6h --> AND (HL) ; PUTMASK + nop ; INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - call __LOAD_S_POSN - push de - call __SET_ATTR - pop de - inc e ; COL = COL + 1 - ld hl, (MAXX) - ld a, e - dec l ; l = MAXX - cp l ; Lower than max? - jp nc, __PRINT_EOL1 + nop ; 2F -> CPL -> INVERSE 1 + ld (hl), a + inc de + inc h ; Next line + djnz __PRCHAR + call __LOAD_S_POSN + push de + call __SET_ATTR + pop de + inc e ; COL = COL + 1 + ld hl, (MAXX) + ld a, e + dec l ; l = MAXX + cp l ; Lower than max? + jp nc, __PRINT_EOL1 __PRINT_CONT: - call __SAVE_S_POSN + call __SAVE_S_POSN __PRINT_CONT2: - exx - ret + exx + ret ; ------------- SPECIAL CHARS (< 32) ----------------- __PRINT_SPECIAL: ; Jumps here if it is a special char - exx - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A + exx + ld hl, __PRINT_TABLE + jp JUMP_HL_PLUS_2A PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx + exx __PRINT_0Dh: ; Called WHEN printing CHR$(13) - call __SCROLL -#line 207 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - call __LOAD_S_POSN + call __SCROLL +#line 209 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + call __LOAD_S_POSN __PRINT_EOL1: ; Another entry called from PRINT when next line required - ld e, 0 + ld e, 0 __PRINT_EOL2: - ld a, d - inc a + ld a, d + inc a __PRINT_AT1_END: - ld hl, (MAXY) - cp l - jr c, __PRINT_EOL_END ; Carry if (MAXY) < d - ld hl, __TVFLAGS - set 1, (hl) - dec a -#line 227 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + ld hl, (MAXY) + cp l + jr c, __PRINT_EOL_END ; Carry if (MAXY) < d + ld hl, __TVFLAGS + set 1, (hl) + dec a +#line 229 "/zxbasic/src/arch/zx48k/library-asm/print.asm" __PRINT_EOL_END: - ld d, a + ld d, a __PRINT_AT2_END: - call __SAVE_S_POSN - exx - ret + call __SAVE_S_POSN + exx + ret __PRINT_COM: - exx - push hl - push de - push bc - call PRINT_COMMA - pop bc - pop de - pop hl - ret + exx + push hl + push de + push bc + call PRINT_COMMA + pop bc + pop de + pop hl + ret __PRINT_TAB: - ld hl, __PRINT_TAB1 - jr __PRINT_SET_STATE + ld hl, __PRINT_TAB1 + jr __PRINT_SET_STATE __PRINT_TAB1: - ld (MEM0), a - exx - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE + ld (MEM0), a + exx + ld hl, __PRINT_TAB2 + jr __PRINT_SET_STATE __PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - push hl - push de - push bc - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - call PRINT_TAB - pop bc - pop de - pop hl - ret + ld a, (MEM0) ; Load tab code (ignore the current one) + push hl + push de + push bc + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl + call PRINT_TAB + pop bc + pop de + pop hl + ret __PRINT_NOP: __PRINT_RESTART: - ld hl, __PRINT_START - jr __PRINT_SET_STATE + ld hl, __PRINT_START + jr __PRINT_SET_STATE __PRINT_AT: - ld hl, __PRINT_AT1 + ld hl, __PRINT_AT1 __PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + exx + ret __PRINT_AT1: ; Jumps here if waiting for 1st parameter - exx - ld hl, __PRINT_AT2 - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - jr __PRINT_AT1_END + exx + ld hl, __PRINT_AT2 + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + jr __PRINT_AT1_END __PRINT_AT2: - exx - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - call __LOAD_S_POSN - ld e, a - ld hl, (MAXX) - cp l - jr c, __PRINT_AT2_END - jr __PRINT_EOL1 + exx + ld hl, __PRINT_START + ld (PRINT_JUMP_STATE), hl ; Saves next entry call + call __LOAD_S_POSN + ld e, a + ld hl, (MAXX) + cp l + jr c, __PRINT_AT2_END + jr __PRINT_EOL1 __PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jp nz, __PRINT_AT2_END - ld hl, (MAXX) - ld e, l - dec e - dec e - dec d - cp d - jp nz, __PRINT_AT2_END - ld d, h - dec d - jp __PRINT_AT2_END + call __LOAD_S_POSN ; Gets current screen position + dec e + ld a, -1 + cp e + jp nz, __PRINT_AT2_END + ld hl, (MAXX) + ld e, l + dec e + dec e + dec d + cp d + jp nz, __PRINT_AT2_END + ld d, h + dec d + jp __PRINT_AT2_END __PRINT_INK: - ld hl, __PRINT_INK2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INK2 + jp __PRINT_SET_STATE __PRINT_INK2: - exx - call INK_TMP - jp __PRINT_RESTART + exx + call INK_TMP + jp __PRINT_RESTART __PRINT_PAP: - ld hl, __PRINT_PAP2 - jp __PRINT_SET_STATE + ld hl, __PRINT_PAP2 + jp __PRINT_SET_STATE __PRINT_PAP2: - exx - call PAPER_TMP - jp __PRINT_RESTART + exx + call PAPER_TMP + jp __PRINT_RESTART __PRINT_FLA: - ld hl, __PRINT_FLA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_FLA2 + jp __PRINT_SET_STATE __PRINT_FLA2: - exx - call FLASH_TMP - jp __PRINT_RESTART + exx + call FLASH_TMP + jp __PRINT_RESTART __PRINT_BRI: - ld hl, __PRINT_BRI2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BRI2 + jp __PRINT_SET_STATE __PRINT_BRI2: - exx - call BRIGHT_TMP - jp __PRINT_RESTART + exx + call BRIGHT_TMP + jp __PRINT_RESTART __PRINT_INV: - ld hl, __PRINT_INV2 - jp __PRINT_SET_STATE + ld hl, __PRINT_INV2 + jp __PRINT_SET_STATE __PRINT_INV2: - exx - call INVERSE_TMP - jp __PRINT_RESTART + exx + call INVERSE_TMP + jp __PRINT_RESTART __PRINT_OVR: - ld hl, __PRINT_OVR2 - jp __PRINT_SET_STATE + ld hl, __PRINT_OVR2 + jp __PRINT_SET_STATE __PRINT_OVR2: - exx - call OVER_TMP - jp __PRINT_RESTART + exx + call OVER_TMP + jp __PRINT_RESTART __PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE + ld hl, __PRINT_BOLD2 + jp __PRINT_SET_STATE __PRINT_BOLD2: - exx - call BOLD_TMP - jp __PRINT_RESTART + exx + call BOLD_TMP + jp __PRINT_RESTART __PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE + ld hl, __PRINT_ITA2 + jp __PRINT_SET_STATE __PRINT_ITA2: - exx - call ITALIC_TMP - jp __PRINT_RESTART + exx + call ITALIC_TMP + jp __PRINT_RESTART __BOLD: - push hl - ld hl, MEM0 - ld b, 8 + push hl + ld hl, MEM0 + ld b, 8 __BOLD_LOOP: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz __BOLD_LOOP - pop hl - ld de, MEM0 - ret + ld a, (de) + ld c, a + rlca + or c + ld (hl), a + inc hl + inc de + djnz __BOLD_LOOP + pop hl + ld de, MEM0 + ret __ITALIC: - push hl - ld hl, MEM0 - ex de, hl - ld bc, 8 - ldir - ld hl, MEM0 - srl (hl) - inc hl - srl (hl) - inc hl - srl (hl) - inc hl - inc hl - inc hl - sla (hl) - inc hl - sla (hl) - inc hl - sla (hl) - pop hl - ld de, MEM0 - ret + push hl + ld hl, MEM0 + ex de, hl + ld bc, 8 + ldir + ld hl, MEM0 + srl (hl) + inc hl + srl (hl) + inc hl + srl (hl) + inc hl + inc hl + inc hl + sla (hl) + inc hl + sla (hl) + inc hl + sla (hl) + pop hl + ld de, MEM0 + ret PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 + call __LOAD_S_POSN + ld a, e + and 16 + add a, 16 PRINT_TAB: - PROC - LOCAL LOOP, CONTINUE - inc a - call __LOAD_S_POSN ; e = current row - ld d, a - ld a, e - cp 21h - jr nz, CONTINUE - ld e, -1 + PROC + LOCAL LOOP, CONTINUE + inc a + call __LOAD_S_POSN ; e = current row + ld d, a + ld a, e + cp 21h + jr nz, CONTINUE + ld e, -1 CONTINUE: - ld a, d - inc e - sub e ; A = A - E - and 31 ; - ret z ; Already at position E - ld b, a + ld a, d + inc e + sub e ; A = A - E + and 31 ; + ret z ; Already at position E + ld b, a LOOP: - ld a, ' ' - push bc - exx - call __PRINTCHAR - exx - pop bc - djnz LOOP - ret - ENDP + ld a, ' ' + push bc + exx + call __PRINTCHAR + exx + pop bc + djnz LOOP + ret + ENDP PRINT_AT: ; Changes cursor to ROW, COL - ; COL in A register - ; ROW in stack - pop hl ; Ret address - ex (sp), hl ; callee H = ROW - ld l, a - ex de, hl - call __IN_SCREEN - ret nc ; Return if out of screen - ld hl, __TVFLAGS - res 1, (hl) -#line 483 "/zxbasic/src/arch/zx48k/library-asm/print.asm" - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __BOLD - LOCAL __BOLD_LOOP - LOCAL __ITALIC - LOCAL __PRINT_EOL1 - LOCAL __PRINT_EOL2 - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_AT2_END - LOCAL __PRINT_BOLD - LOCAL __PRINT_BOLD2 - LOCAL __PRINT_ITA - LOCAL __PRINT_ITA2 - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 + ; COL in A register + ; ROW in stack + pop hl ; Ret address + ex (sp), hl ; callee H = ROW + ld l, a + ex de, hl + call __IN_SCREEN + ret nc ; Return if out of screen + ld hl, __TVFLAGS + res 1, (hl) +#line 485 "/zxbasic/src/arch/zx48k/library-asm/print.asm" + jp __SAVE_S_POSN + LOCAL __PRINT_COM + LOCAL __BOLD + LOCAL __BOLD_LOOP + LOCAL __ITALIC + LOCAL __PRINT_EOL1 + LOCAL __PRINT_EOL2 + LOCAL __PRINT_AT1 + LOCAL __PRINT_AT2 + LOCAL __PRINT_AT2_END + LOCAL __PRINT_BOLD + LOCAL __PRINT_BOLD2 + LOCAL __PRINT_ITA + LOCAL __PRINT_ITA2 + LOCAL __PRINT_INK + LOCAL __PRINT_PAP + LOCAL __PRINT_SET_STATE + LOCAL __PRINT_TABLE + LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 __PRINT_TABLE: ; Jump table for 0 .. 22 codes - DW __PRINT_NOP ; 0 - DW __PRINT_NOP ; 1 - DW __PRINT_NOP ; 2 - DW __PRINT_NOP ; 3 - DW __PRINT_NOP ; 4 - DW __PRINT_NOP ; 5 - DW __PRINT_COM ; 6 COMMA - DW __PRINT_NOP ; 7 - DW __PRINT_DEL ; 8 DEL - DW __PRINT_NOP ; 9 - DW __PRINT_NOP ; 10 - DW __PRINT_NOP ; 11 - DW __PRINT_NOP ; 12 - DW __PRINT_0Dh ; 13 - DW __PRINT_BOLD ; 14 - DW __PRINT_ITA ; 15 - DW __PRINT_INK ; 16 - DW __PRINT_PAP ; 17 - DW __PRINT_FLA ; 18 - DW __PRINT_BRI ; 19 - DW __PRINT_INV ; 20 - DW __PRINT_OVR ; 21 - DW __PRINT_AT ; 22 AT - DW __PRINT_TAB ; 23 TAB - ENDP + DW __PRINT_NOP ; 0 + DW __PRINT_NOP ; 1 + DW __PRINT_NOP ; 2 + DW __PRINT_NOP ; 3 + DW __PRINT_NOP ; 4 + DW __PRINT_NOP ; 5 + DW __PRINT_COM ; 6 COMMA + DW __PRINT_NOP ; 7 + DW __PRINT_DEL ; 8 DEL + DW __PRINT_NOP ; 9 + DW __PRINT_NOP ; 10 + DW __PRINT_NOP ; 11 + DW __PRINT_NOP ; 12 + DW __PRINT_0Dh ; 13 + DW __PRINT_BOLD ; 14 + DW __PRINT_ITA ; 15 + DW __PRINT_INK ; 16 + DW __PRINT_PAP ; 17 + DW __PRINT_FLA ; 18 + DW __PRINT_BRI ; 19 + DW __PRINT_INV ; 20 + DW __PRINT_OVR ; 21 + DW __PRINT_AT ; 22 AT + DW __PRINT_TAB ; 23 TAB + ENDP + pop namespace #line 25 "usr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/printnum.asm" + push namespace core __PRINTU_START: - PROC - LOCAL __PRINTU_CONT - ld a, b - or a - jp nz, __PRINTU_CONT - ld a, '0' - jp __PRINT_DIGIT + PROC + LOCAL __PRINTU_CONT + ld a, b + or a + jp nz, __PRINTU_CONT + ld a, '0' + jp __PRINT_DIGIT __PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP + pop af + push bc + call __PRINT_DIGIT + pop bc + djnz __PRINTU_CONT + ret + ENDP __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER mus preserve registers - ld a, '-' - jp __PRINT_DIGIT + ld a, '-' + jp __PRINT_DIGIT __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg16.asm" ; Negates HL value (16 bit) + push namespace core __ABS16: - bit 7, h - ret z + bit 7, h + ret z __NEGHL: - ld a, l ; HL = -HL - cpl - ld l, a - ld a, h - cpl - ld h, a - inc hl - ret + ld a, l ; HL = -HL + cpl + ld l, a + ld a, h + cpl + ld h, a + inc hl + ret + pop namespace #line 5 "/zxbasic/src/arch/zx48k/library-asm/div16.asm" + push namespace core __DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl + ; HL = Dividend, Stack Top = Divisor + ; -- OBSOLETE ; Now uses FASTCALL convention + ; ex de, hl ; pop hl ; Return address ; ex (sp), hl ; CALLEE Convention __DIVU16_FAST: @@ -1051,76 +1090,79 @@ __DIV16NOADD: ld l, c ret ; HL = quotient, DE = Mudulus __MODU16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVU16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret __DIVI16: ; 16 bit signed division - ; --- The following is OBSOLETE --- - ; ex de, hl - ; pop hl - ; ex (sp), hl ; CALLEE Convention + ; --- The following is OBSOLETE --- + ; ex de, hl + ; pop hl + ; ex (sp), hl ; CALLEE Convention __DIVI16_FAST: - ld a, d - xor h - ex af, af' ; BIT 7 of a contains result - bit 7, d ; DE is negative? - jr z, __DIVI16A - ld a, e ; DE = -DE - cpl - ld e, a - ld a, d - cpl - ld d, a - inc de + ld a, d + xor h + ex af, af' ; BIT 7 of a contains result + bit 7, d ; DE is negative? + jr z, __DIVI16A + ld a, e ; DE = -DE + cpl + ld e, a + ld a, d + cpl + ld d, a + inc de __DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL + bit 7, h ; HL is negative? + call nz, __NEGHL __DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive + call __DIVU16_FAST + ex af, af' + or a + ret p ; return if positive jp __NEGHL __MODI16: ; 16 bit modulus - ; HL = Dividend, Stack Top = Divisor + ; HL = Dividend, Stack Top = Divisor ;ex de, hl ;pop hl ;ex (sp), hl ; CALLEE Convention call __DIVI16_FAST ex de, hl ; hl = reminder (modulus) - ; de = quotient + ; de = quotient ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/printi16.asm" + push namespace core __PRINTI16: ; Prints a 16bits signed in HL - ; Converts 16 to 32 bits - PROC - LOCAL __PRINTU_LOOP - ld a, h - or a - jp p, __PRINTU16 - call __PRINT_MINUS - call __NEGHL + ; Converts 16 to 32 bits + PROC + LOCAL __PRINTU_LOOP + ld a, h + or a + jp p, __PRINTU16 + call __PRINT_MINUS + call __NEGHL __PRINTU16: - ld b, 0 + ld b, 0 __PRINTU_LOOP: - ld a, h - or l - jp z, __PRINTU_START - push bc - ld de, 10 - call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus - pop bc - ld a, e - or '0' ; Stores ASCII digit (must be print in reversed order) - push af - inc b - jp __PRINTU_LOOP ; Uses JP in loops - ENDP + ld a, h + or l + jp z, __PRINTU_START + push bc + ld de, 10 + call __DIVU16_FAST ; Divides by DE. DE = MODULUS at exit. Since < 256, E = Modulus + pop bc + ld a, e + or '0' ; Stores ASCII digit (must be print in reversed order) + push af + inc b + jp __PRINTU_LOOP ; Uses JP in loops + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/printu16.asm" #line 26 "usr0.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/usr_str.asm" @@ -1253,9 +1295,10 @@ __PRINTU_LOOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -1263,37 +1306,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -1303,124 +1347,127 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 11 "/zxbasic/src/arch/zx48k/library-asm/usr_str.asm" + push namespace core USR_STR: PROC ex af, af' ; Saves A flag - ld a, h - or l - jr z, USR_ERROR ; a$ = NULL => Invalid Arg + ld a, h + or l + jr z, USR_ERROR ; a$ = NULL => Invalid Arg ld d, h ; Saves HL in DE, for ld e, l ; later usage - ld c, (hl) - inc hl - ld a, (hl) - or c - jr z, USR_ERROR ; a$ = "" => Invalid Arg - inc hl - ld a, (hl) ; Only the 1st char is needed - and 11011111b ; Convert it to UPPER CASE - sub 144 ; CODE(UDG "A") - jr nc, CONT - add a, 144 ; It was a letter - sub 'A' + ld c, (hl) + inc hl + ld a, (hl) + or c + jr z, USR_ERROR ; a$ = "" => Invalid Arg + inc hl + ld a, (hl) ; Only the 1st char is needed + and 11011111b ; Convert it to UPPER CASE + sub 144 ; CODE(UDG "A") + jr nc, CONT + add a, 144 ; It was a letter + sub 'A' LOCAL CONT CONT: - ld l, a - ld h, 0 - add hl, hl - add hl, hl - add hl, hl ; hl = A * 8 - ld bc, (UDG) - add hl, bc + ld l, a + ld h, 0 + add hl, hl + add hl, hl + add hl, hl ; hl = A * 8 + ld bc, (UDG) + add hl, bc ;; Now checks if the string must be released ex af, af' ; Recovers A flag or a @@ -1429,16 +1476,17 @@ CONT: ex de, hl ; Recovers original HL value call __MEM_FREE pop hl - ret + ret USR_ERROR: ex de, hl ; Recovers original HL value ex af, af' ; Recovers A flag or a call nz, __MEM_FREE - ld a, ERROR_InvalidArg - ld (ERR_NR), a - ld hl, 0 - ret - ENDP + ld a, ERROR_InvalidArg + ld (ERR_NR), a + ld hl, 0 + ret + ENDP + pop namespace #line 27 "usr0.bas" END diff --git a/tests/functional/utf-8-bom-bas.asm b/tests/functional/utf-8-bom-bas.asm index 2bf0d06c6..0628c1ca8 100644 --- a/tests/functional/utf-8-bom-bas.asm +++ b/tests/functional/utf-8-bom-bas.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,25 +8,25 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__datosniveles: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/valcrash1.asm b/tests/functional/valcrash1.asm index b9c108e00..969e33606 100644 --- a/tests/functional/valcrash1.asm +++ b/tests/functional/valcrash1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,38 +8,38 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _c: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld de, __LABEL0 ld hl, _c - call __STORE_STR + call core.__STORE_STR ld hl, (_c) - call __LOADSTR + call core.__LOADSTR push hl call _test ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -60,15 +60,15 @@ _test: ld l, (ix+4) ld h, (ix+5) xor a - call VAL + call core.VAL ld hl, -5 - call __PSTOREF + call core.__PSTOREF _test__leave: ex af, af' exx ld l, (ix+4) ld h, (ix+5) - call __MEM_FREE + call core.__MEM_FREE ex af, af' exx ld sp, ix @@ -206,9 +206,10 @@ __LABEL0: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -216,37 +217,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/free.asm" ; --------------------------------------------------------------------- ; MEM_FREE @@ -256,94 +258,96 @@ __MEM_INIT2: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 57 "valcrash1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" @@ -409,6 +413,7 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -438,6 +443,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -450,125 +456,129 @@ __STOP: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL + push namespace core __ILOADSTR: ; This is the indirect pointer entry HL = (HL) - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) - ld l, a + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) + ld l, a __LOADSTR: ; __FASTCALL__ entry - ld a, h - or l - ret z ; Return if NULL - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(a$) - inc bc - inc bc ; BC = LEN(a$) + 2 (two bytes for length) - push hl - push bc - call __MEM_ALLOC - pop bc ; Recover length - pop de ; Recover origin - ld a, h - or l - ret z ; Return if NULL (No memory) - ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE - push de ; Saves destiny start - ldir ; Copies string (length number included) - pop hl ; Recovers destiny in hl as result - ret + ld a, h + or l + ret z ; Return if NULL + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(a$) + inc bc + inc bc ; BC = LEN(a$) + 2 (two bytes for length) + push hl + push bc + call __MEM_ALLOC + pop bc ; Recover length + pop de ; Recover origin + ld a, h + or l + ret z ; Return if NULL (No memory) + ex de, hl ; ldir takes HL as source, DE as destiny, so SWAP HL,DE + push de ; Saves destiny start + ldir ; Copies string (length number included) + pop hl ; Recovers destiny in hl as result + ret + pop namespace #line 58 "valcrash1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stores FP number in A ED CB at location HL+IX @@ -576,41 +586,45 @@ __LOADSTR: ; __FASTCALL__ entry ; IX = Stack Frame ; A ED CB = FP Number #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/pstoref.asm" ; Stored a float number in A ED CB into the address pointed by IX + HL + push namespace core __PSTOREF: - push de + push de ex de, hl ; DE <- HL push ix - pop hl ; HL <- IX + pop hl ; HL <- IX add hl, de ; HL <- IX + DE - pop de + pop de jp __STOREF + pop namespace #line 59 "valcrash1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" ; vim:ts=4:et:sw=4 @@ -704,132 +718,137 @@ __PSTOREF: ; memory garbage. ; ; --------------------------------------------------------------------- + push namespace core __REALLOC: ; Reallocates block pointed by HL, with new length BC - PROC - LOCAL __REALLOC_END - ld a, h - or l - jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc - ld e, (hl) - inc hl - ld d, (hl) ; DE = First 2 bytes of HL block - push hl - exx - pop de - inc de ; DE' <- HL + 2 - exx ; DE' <- HL (Saves current pointer into DE') - dec hl ; HL = Block start - push de - push bc - call __MEM_FREE ; Frees current block - pop bc - push bc - call __MEM_ALLOC ; Gets a new block of length BC - pop bc - pop de - ld a, h - or l - ret z ; Return if HL == NULL (No memory) - ld (hl), e - inc hl - ld (hl), d - inc hl ; Recovers first 2 bytes in HL - dec bc - dec bc ; BC = BC - 2 (Two bytes copied) - ld a, b - or c - jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) - exx - push de - exx - pop de ; DE <- DE' ; Start of remaining block - push hl ; Saves current Block + 2 start - ex de, hl ; Exchanges them: DE is destiny block - ldir ; Copies BC Bytes - pop hl ; Recovers Block + 2 start + PROC + LOCAL __REALLOC_END + ld a, h + or l + jp z, __MEM_ALLOC ; If HL == NULL, just do a malloc + ld e, (hl) + inc hl + ld d, (hl) ; DE = First 2 bytes of HL block + push hl + exx + pop de + inc de ; DE' <- HL + 2 + exx ; DE' <- HL (Saves current pointer into DE') + dec hl ; HL = Block start + push de + push bc + call __MEM_FREE ; Frees current block + pop bc + push bc + call __MEM_ALLOC ; Gets a new block of length BC + pop bc + pop de + ld a, h + or l + ret z ; Return if HL == NULL (No memory) + ld (hl), e + inc hl + ld (hl), d + inc hl ; Recovers first 2 bytes in HL + dec bc + dec bc ; BC = BC - 2 (Two bytes copied) + ld a, b + or c + jp z, __REALLOC_END ; Ret if nothing to copy (BC == 0) + exx + push de + exx + pop de ; DE <- DE' ; Start of remaining block + push hl ; Saves current Block + 2 start + ex de, hl ; Exchanges them: DE is destiny block + ldir ; Copies BC Bytes + pop hl ; Recovers Block + 2 start __REALLOC_END: - dec hl ; Set HL - dec hl ; To begin of block - ret - ENDP + dec hl ; Set HL + dec hl ; To begin of block + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/strcpy.asm" ; String library + push namespace core __STRASSIGN: ; Performs a$ = b$ (HL = address of a$; DE = Address of b$) - PROC - LOCAL __STRREALLOC - LOCAL __STRCONTINUE - LOCAL __B_IS_NULL - LOCAL __NOTHING_TO_COPY - ld b, d - ld c, e - ld a, b - or c - jr z, __B_IS_NULL - ex de, hl - ld c, (hl) - inc hl - ld b, (hl) - dec hl ; BC = LEN(b$) - ex de, hl ; DE = &b$ + PROC + LOCAL __STRREALLOC + LOCAL __STRCONTINUE + LOCAL __B_IS_NULL + LOCAL __NOTHING_TO_COPY + ld b, d + ld c, e + ld a, b + or c + jr z, __B_IS_NULL + ex de, hl + ld c, (hl) + inc hl + ld b, (hl) + dec hl ; BC = LEN(b$) + ex de, hl ; DE = &b$ __B_IS_NULL: ; Jumps here if B$ pointer is NULL - inc bc - inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) - push de - push hl - ld a, h - or l - jr z, __STRREALLOC - dec hl - ld d, (hl) - dec hl - ld e, (hl) ; DE = MEMBLOCKSIZE(a$) - dec de - dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) - ld h, b - ld l, c ; HL = LEN(b$) + 2 => Minimum block size required - ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 - or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) - sbc hl, de ; Carry if len(b$) > Blocklen(a$) - jr c, __STRREALLOC ; No need to realloc - ; Need to reallocate at least to len(b$) + 2 - ex de, hl ; DE = Remaining bytes in a$ mem block. - ld hl, 4 - sbc hl, de ; if remaining bytes < 4 we can continue - jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes + inc bc + inc bc ; BC = BC + 2 ; (LEN(b$) + 2 bytes for storing length) + push de + push hl + ld a, h + or l + jr z, __STRREALLOC + dec hl + ld d, (hl) + dec hl + ld e, (hl) ; DE = MEMBLOCKSIZE(a$) + dec de + dec de ; DE = DE - 2 ; (Membloksize takes 2 bytes for memblock length) + ld h, b + ld l, c ; HL = LEN(b$) + 2 => Minimum block size required + ex de, hl ; Now HL = BLOCKSIZE(a$), DE = LEN(b$) + 2 + or a ; Prepare to subtract BLOCKSIZE(a$) - LEN(b$) + sbc hl, de ; Carry if len(b$) > Blocklen(a$) + jr c, __STRREALLOC ; No need to realloc + ; Need to reallocate at least to len(b$) + 2 + ex de, hl ; DE = Remaining bytes in a$ mem block. + ld hl, 4 + sbc hl, de ; if remaining bytes < 4 we can continue + jr nc,__STRCONTINUE ; Otherwise, we realloc, to free some bytes __STRREALLOC: - pop hl - call __REALLOC ; Returns in HL a new pointer with BC bytes allocated - push hl + pop hl + call __REALLOC ; Returns in HL a new pointer with BC bytes allocated + push hl __STRCONTINUE: ; Pops hl and de SWAPPED - pop de ; DE = &a$ - pop hl ; HL = &b$ - ld a, d ; Return if not enough memory for new length - or e - ret z ; Return if DE == NULL (0) + pop de ; DE = &a$ + pop hl ; HL = &b$ + ld a, d ; Return if not enough memory for new length + or e + ret z ; Return if DE == NULL (0) __STRCPY: ; Copies string pointed by HL into string pointed by DE - ; Returns DE as HL (new pointer) - ld a, h - or l - jr z, __NOTHING_TO_COPY - ld c, (hl) - inc hl - ld b, (hl) - dec hl - inc bc - inc bc - push de - ldir - pop hl - ret + ; Returns DE as HL (new pointer) + ld a, h + or l + jr z, __NOTHING_TO_COPY + ld c, (hl) + inc hl + ld b, (hl) + dec hl + inc bc + inc bc + push de + ldir + pop hl + ret __NOTHING_TO_COPY: - ex de, hl - ld (hl), e - inc hl - ld (hl), d - dec hl - ret - ENDP + ex de, hl + ld (hl), e + inc hl + ld (hl), d + dec hl + ret + ENDP + pop namespace #line 14 "/zxbasic/src/arch/zx48k/library-asm/storestr.asm" + push namespace core __PISTORE_STR: ; Indirect assignement at (IX + BC) push ix pop hl @@ -854,18 +873,20 @@ __STORE_STR: ld (hl), d ; Stores a$ ptr into elemem ptr pop hl ; Returns ptr to b$ in HL (Caller might needed to free it from memory) ret + pop namespace #line 60 "valcrash1.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/val.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -880,33 +901,35 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/val.asm" + push namespace core VAL: ; Computes VAL(a$) using ROM FP-CALC - ; HL = address of a$ - ; Returns FP number in C ED LH registers - ; A Register = 1 => Free a$ on return - PROC - LOCAL STK_STO_S - LOCAL __RET_ZERO - LOCAL ERR_SP - LOCAL STKBOT - LOCAL RECLAIM1 + ; HL = address of a$ + ; Returns FP number in C ED LH registers + ; A Register = 1 => Free a$ on return + PROC + LOCAL STK_STO_S + LOCAL __RET_ZERO + LOCAL ERR_SP + LOCAL STKBOT + LOCAL RECLAIM1 LOCAL CH_ADD - LOCAL __VAL_ERROR - LOCAL __VAL_EMPTY + LOCAL __VAL_ERROR + LOCAL __VAL_EMPTY LOCAL SET_MIN RECLAIM1 EQU 6629 STKBOT EQU 23651 @@ -915,72 +938,73 @@ VAL: ; Computes VAL(a$) using ROM FP-CALC STK_STO_S EQU 2AB2h SET_MIN EQU 16B0h ld d, a ; Preserves A register in DE - ld a, h - or l - jr z, __RET_ZERO ; NULL STRING => Return 0 + ld a, h + or l + jr z, __RET_ZERO ; NULL STRING => Return 0 push de ; Saves A Register (now in D) - push hl ; Not null string. Save its address for later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string - ex de, hl ; DE = String start + push hl ; Not null string. Save its address for later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string + ex de, hl ; DE = String start ld hl, (CH_ADD) push hl - ld hl, (STKBOT) - push hl - ld hl, (ERR_SP) - push hl + ld hl, (STKBOT) + push hl + ld hl, (ERR_SP) + push hl ;; Now put our error handler on ERR_SP - ld hl, __VAL_ERROR - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - call STK_STO_S ; Enter it on the stack - ld b, 1Dh ; "VAL" - rst 28h ; ROM CALC - defb 1Dh ; VAL - defb 38h ; END CALC - pop hl ; Discards our current error handler - pop hl - ld (ERR_SP), hl ; Restores ERR_SP - pop de ; old STKBOT - ld hl, (STKBOT) ; current SKTBOT - call RECLAIM1 ; Recover unused space + ld hl, __VAL_ERROR + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl + call STK_STO_S ; Enter it on the stack + ld b, 1Dh ; "VAL" + rst 28h ; ROM CALC + defb 1Dh ; VAL + defb 38h ; END CALC + pop hl ; Discards our current error handler + pop hl + ld (ERR_SP), hl ; Restores ERR_SP + pop de ; old STKBOT + ld hl, (STKBOT) ; current SKTBOT + call RECLAIM1 ; Recover unused space pop hl ; Discards old CH_ADD value - pop hl ; String pointer - pop af ; Deletion flag - or a - call nz, __MEM_FREE ; Frees string content before returning + pop hl ; String pointer + pop af ; Deletion flag + or a + call nz, __MEM_FREE ; Frees string content before returning ld a, ERROR_Ok ; Sets OK in the result ld (ERR_NR), a - jp __FPSTACK_POP ; Recovers result and return from there + jp __FPSTACK_POP ; Recovers result and return from there __VAL_ERROR: ; Jumps here on ERROR - pop hl - ld (ERR_SP), hl ; Restores ERR_SP - ld hl, (STKBOT) ; current SKTBOT - pop de ; old STKBOT + pop hl + ld (ERR_SP), hl ; Restores ERR_SP + ld hl, (STKBOT) ; current SKTBOT + pop de ; old STKBOT pop hl ld (CH_ADD), hl ; Recovers old CH_ADD call 16B0h ; Resets temporary areas after an error __VAL_EMPTY: ; Jumps here on empty string - pop hl ; Recovers initial string address - pop af ; String flag: If not 0 => it's temporary - or a - call nz, __MEM_FREE ; Frees "" string + pop hl ; Recovers initial string address + pop af ; String flag: If not 0 => it's temporary + or a + call nz, __MEM_FREE ; Frees "" string __RET_ZERO: ; Returns 0 Floating point on error - ld a, ERROR_InvalidArg - ld (ERR_NR), a - xor a - ld b, a - ld c, a - ld d, b - ld e, c - ret - ENDP + ld a, ERROR_InvalidArg + ld (ERR_NR), a + xor a + ld b, a + ld c, a + ld d, b + ld e, c + ret + ENDP + pop namespace #line 61 "valcrash1.bas" END diff --git a/tests/functional/valcrash2.asm b/tests/functional/valcrash2.asm index 51089023c..292e5b834 100644 --- a/tests/functional/valcrash2.asm +++ b/tests/functional/valcrash2.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,50 +8,50 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - call __MEM_INIT - jp __MAIN_PROGRAM__ -__CALL_BACK__: + call core.__MEM_INIT + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines HEAP SIZE -ZXBASIC_HEAP_SIZE EQU 4768 -ZXBASIC_MEM_HEAP: +core.ZXBASIC_HEAP_SIZE EQU 4768 +core.ZXBASIC_MEM_HEAP: DEFS 4768 ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 _b: DEFB 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_b) xor a - call VAL + call core.VAL ld hl, _a - call __STOREF + call core.__STOREF ld de, (_b) ld hl, (_b) - call __ADDSTR + call core.__ADDSTR ld a, 1 - call VAL + call core.VAL ld hl, _a - call __STOREF - call INKEY + call core.__STOREF + call core.INKEY ld a, 1 - call VAL + call core.VAL ld hl, _a - call __STOREF + call core.__STOREF ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -129,6 +129,7 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" ; Simple error control routines ; vim:ts=4:et: + push namespace core ERR_NR EQU 23610 ; Error code system variable ; Error code definitions (as in ZX spectrum manual) ; Set error code with: @@ -158,6 +159,7 @@ __ERROR_CODE: __STOP: ld (ERR_NR), a ret + pop namespace #line 69 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" ; vim: ts=4:et:sw=4: @@ -223,9 +225,10 @@ __STOP: ; __MEM_INIT must be called to initalize this library with the ; standard parameters ; --------------------------------------------------------------------- + push namespace core __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and - ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start - ld de, ZXBASIC_HEAP_SIZE ; Change this with your size + ld hl, ZXBASIC_MEM_HEAP ; Change this with other address of heap start + ld de, ZXBASIC_HEAP_SIZE ; Change this with your size ; --------------------------------------------------------------------- ; __MEM_INIT2 initalizes this library ; Parameters: @@ -233,37 +236,38 @@ __MEM_INIT: ; Initializes the library using (RAMTOP) as start, and ; DE : Length in bytes of the Memory Heap ; --------------------------------------------------------------------- __MEM_INIT2: - ; HL as TOP - PROC - dec de - dec de - dec de - dec de ; DE = length - 4; HL = start - ; This is done, because we require 4 bytes for the empty dummy-header block - xor a - ld (hl), a - inc hl - ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 - inc hl - ld b, h - ld c, l - inc bc - inc bc ; BC = starts of next block - ld (hl), c - inc hl - ld (hl), b - inc hl ; Pointer to next block - ld (hl), e - inc hl - ld (hl), d - inc hl ; Block size (should be length - 4 at start); This block contains all the available memory - ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) - inc hl - ld (hl), a - ld a, 201 - ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again - ret - ENDP + ; HL as TOP + PROC + dec de + dec de + dec de + dec de ; DE = length - 4; HL = start + ; This is done, because we require 4 bytes for the empty dummy-header block + xor a + ld (hl), a + inc hl + ld (hl), a ; First "free" block is a header: size=0, Pointer=&(Block) + 4 + inc hl + ld b, h + ld c, l + inc bc + inc bc ; BC = starts of next block + ld (hl), c + inc hl + ld (hl), b + inc hl ; Pointer to next block + ld (hl), e + inc hl + ld (hl), d + inc hl ; Block size (should be length - 4 at start); This block contains all the available memory + ld (hl), a ; NULL (0000h) ; No more blocks (a list with a single block) + inc hl + ld (hl), a + ld a, 201 + ld (__MEM_INIT), a; "Pokes" with a RET so ensure this routine is not called again + ret + ENDP + pop namespace #line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC @@ -276,269 +280,279 @@ __MEM_INIT2: ; HL = Pointer to the allocated block in memory. Returns 0 (NULL) ; if the block could not be allocated (out of memory) ; --------------------------------------------------------------------- + push namespace core MEM_ALLOC: __MEM_ALLOC: ; Returns the 1st free block found of the given length (in BC) - PROC - LOCAL __MEM_LOOP - LOCAL __MEM_DONE - LOCAL __MEM_SUBTRACT - LOCAL __MEM_START - LOCAL TEMP, TEMP0 + PROC + LOCAL __MEM_LOOP + LOCAL __MEM_DONE + LOCAL __MEM_SUBTRACT + LOCAL __MEM_START + LOCAL TEMP, TEMP0 TEMP EQU TEMP0 + 1 - ld hl, 0 - ld (TEMP), hl + ld hl, 0 + ld (TEMP), hl __MEM_START: - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start - inc bc - inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + inc bc + inc bc ; BC = BC + 2 ; block size needs 2 extra bytes for hidden pointer __MEM_LOOP: ; Loads lengh at (HL, HL+). If Lenght >= BC, jump to __MEM_DONE - ld a, h ; HL = NULL (No memory available?) - or l -#line 111 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ret z ; NULL + ld a, h ; HL = NULL (No memory available?) + or l #line 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __MEM_DONE - pop hl - ld (TEMP), hl - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) - ex de, hl - jp __MEM_LOOP + ret z ; NULL +#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" + ; HL = Pointer to Free block + ld e, (hl) + inc hl + ld d, (hl) + inc hl ; DE = Block Length + push hl ; HL = *pointer to -> next block + ex de, hl + or a ; CF = 0 + sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) + jp nc, __MEM_DONE + pop hl + ld (TEMP), hl + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) + ex de, hl + jp __MEM_LOOP __MEM_DONE: ; A free block has been found. - ; Check if at least 4 bytes remains free (HL >= 4) - push hl - exx ; exx to preserve bc - pop hl - ld bc, 4 - or a - sbc hl, bc - exx - jp nc, __MEM_SUBTRACT - ; At this point... - ; less than 4 bytes remains free. So we return this block entirely - ; We must link the previous block with the next to this one - ; (DE) => Pointer to next block - ; (TEMP) => &(previous->next) - pop hl ; Discard current block pointer - push de - ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex de, hl ; HL = Previous block pointer; DE = Next block pointer + ; Check if at least 4 bytes remains free (HL >= 4) + push hl + exx ; exx to preserve bc + pop hl + ld bc, 4 + or a + sbc hl, bc + exx + jp nc, __MEM_SUBTRACT + ; At this point... + ; less than 4 bytes remains free. So we return this block entirely + ; We must link the previous block with the next to this one + ; (DE) => Pointer to next block + ; (TEMP) => &(previous->next) + pop hl ; Discard current block pointer + push de + ex de, hl ; DE = Previous block pointer; (HL) = Next block pointer + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex de, hl ; HL = Previous block pointer; DE = Next block pointer TEMP0: - ld hl, 0 ; Pre-previous block pointer - ld (hl), e - inc hl - ld (hl), d ; LINKED - pop hl ; Returning block. - ret + ld hl, 0 ; Pre-previous block pointer + ld (hl), e + inc hl + ld (hl), d ; LINKED + pop hl ; Returning block. + ret __MEM_SUBTRACT: - ; At this point we have to store HL value (Length - BC) into (DE - 2) - ex de, hl - dec hl - ld (hl), d - dec hl - ld (hl), e ; Store new block length - add hl, de ; New length + DE => free-block start - pop de ; Remove previous HL off the stack - ld (hl), c ; Store length on its 1st word - inc hl - ld (hl), b - inc hl ; Return hl - ret - ENDP + ; At this point we have to store HL value (Length - BC) into (DE - 2) + ex de, hl + dec hl + ld (hl), d + dec hl + ld (hl), e ; Store new block length + add hl, de ; New length + DE => free-block start + pop de ; Remove previous HL off the stack + ld (hl), c ; Store length on its 1st word + inc hl + ld (hl), b + inc hl ; Return hl + ret + ENDP + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/inkey.asm" + push namespace core INKEY: - PROC - LOCAL __EMPTY_INKEY - LOCAL KEY_SCAN - LOCAL KEY_TEST - LOCAL KEY_CODE - ld bc, 3 ; 1 char length string - call __MEM_ALLOC - ld a, h - or l - ret z ; Return if NULL (No memory) - push hl ; Saves memory pointer - call KEY_SCAN - jp nz, __EMPTY_INKEY - call KEY_TEST - jp nc, __EMPTY_INKEY - dec d ; D is expected to be FLAGS so set bit 3 $FF - ; 'L' Mode so no keywords. - ld e, a ; main key to A - ; C is MODE 0 'KLC' from above still. - call KEY_CODE ; routine K-DECODE - pop hl - ld (hl), 1 - inc hl - ld (hl), 0 - inc hl - ld (hl), a - dec hl - dec hl ; HL Points to string result - ret + PROC + LOCAL __EMPTY_INKEY + LOCAL KEY_SCAN + LOCAL KEY_TEST + LOCAL KEY_CODE + ld bc, 3 ; 1 char length string + call __MEM_ALLOC + ld a, h + or l + ret z ; Return if NULL (No memory) + push hl ; Saves memory pointer + call KEY_SCAN + jp nz, __EMPTY_INKEY + call KEY_TEST + jp nc, __EMPTY_INKEY + dec d ; D is expected to be FLAGS so set bit 3 $FF + ; 'L' Mode so no keywords. + ld e, a ; main key to A + ; C is MODE 0 'KLC' from above still. + call KEY_CODE ; routine K-DECODE + pop hl + ld (hl), 1 + inc hl + ld (hl), 0 + inc hl + ld (hl), a + dec hl + dec hl ; HL Points to string result + ret __EMPTY_INKEY: - pop hl - xor a - ld (hl), a - inc hl - ld (hl), a - dec hl - ret + pop hl + xor a + ld (hl), a + inc hl + ld (hl), a + dec hl + ret KEY_SCAN EQU 028Eh KEY_TEST EQU 031Eh KEY_CODE EQU 0333h - ENDP + ENDP + pop namespace #line 34 "valcrash2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" + push namespace core __PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) - push de - ex de, hl ; DE <- HL - push ix - pop hl ; HL <- IX - add hl, de ; HL <- IX + HL - pop de + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de __ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register - ex af, af' - ld a, (hl) - inc hl - ld h, (hl) - ld l, a ; HL = (HL) - ex af, af' + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' __STOREF: ; Stores the given FP number in A EDCB at address HL - ld (hl), a - inc hl - ld (hl), e - inc hl - ld (hl), d - inc hl - ld (hl), c - inc hl - ld (hl), b - ret + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace #line 35 "valcrash2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/strlen.asm" ; Returns len if a string ; If a string is NULL, its len is also 0 ; Result returned in HL + push namespace core __STRLEN: ; Direct FASTCALL entry - ld a, h - or l - ret z - ld a, (hl) - inc hl - ld h, (hl) ; LEN(str) in HL - ld l, a - ret + ld a, h + or l + ret z + ld a, (hl) + inc hl + ld h, (hl) ; LEN(str) in HL + ld l, a + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/strcat.asm" + push namespace core __ADDSTR: ; Implements c$ = a$ + b$ - ; hl = &a$, de = &b$ (pointers) + ; hl = &a$, de = &b$ (pointers) __STRCAT2: ; This routine creates a new string in dynamic space - ; making room for it. Then copies a$ + b$ into it. - ; HL = a$, DE = b$ - PROC - LOCAL __STR_CONT - LOCAL __STRCATEND - push hl - call __STRLEN - ld c, l - ld b, h ; BC = LEN(a$) - ex (sp), hl ; (SP) = LEN (a$), HL = a$ - push hl ; Saves pointer to a$ - inc bc - inc bc ; +2 bytes to store length - ex de, hl - push hl - call __STRLEN - ; HL = len(b$) - add hl, bc ; Total str length => 2 + len(a$) + len(b$) - ld c, l - ld b, h ; BC = Total str length + 2 - call __MEM_ALLOC - pop de ; HL = c$, DE = b$ - ex de, hl ; HL = b$, DE = c$ - ex (sp), hl ; HL = a$, (SP) = b$ - exx - pop de ; D'E' = b$ - exx - pop bc ; LEN(a$) - ld a, d - or e - ret z ; If no memory: RETURN + ; making room for it. Then copies a$ + b$ into it. + ; HL = a$, DE = b$ + PROC + LOCAL __STR_CONT + LOCAL __STRCATEND + push hl + call __STRLEN + ld c, l + ld b, h ; BC = LEN(a$) + ex (sp), hl ; (SP) = LEN (a$), HL = a$ + push hl ; Saves pointer to a$ + inc bc + inc bc ; +2 bytes to store length + ex de, hl + push hl + call __STRLEN + ; HL = len(b$) + add hl, bc ; Total str length => 2 + len(a$) + len(b$) + ld c, l + ld b, h ; BC = Total str length + 2 + call __MEM_ALLOC + pop de ; HL = c$, DE = b$ + ex de, hl ; HL = b$, DE = c$ + ex (sp), hl ; HL = a$, (SP) = b$ + exx + pop de ; D'E' = b$ + exx + pop bc ; LEN(a$) + ld a, d + or e + ret z ; If no memory: RETURN __STR_CONT: - push de ; Address of c$ - ld a, h - or l - jr nz, __STR_CONT1 ; If len(a$) != 0 do copy - ; a$ is NULL => uses HL = DE for transfer - ld h, d - ld l, e - ld (hl), a ; This will copy 00 00 at (DE) location - inc de ; - dec bc ; Ensure BC will be set to 1 in the next step + push de ; Address of c$ + ld a, h + or l + jr nz, __STR_CONT1 ; If len(a$) != 0 do copy + ; a$ is NULL => uses HL = DE for transfer + ld h, d + ld l, e + ld (hl), a ; This will copy 00 00 at (DE) location + inc de ; + dec bc ; Ensure BC will be set to 1 in the next step __STR_CONT1: ; Copies a$ (HL) into c$ (DE) - inc bc - inc bc ; BC = BC + 2 - ldir ; MEMCOPY: c$ = a$ - pop hl ; HL = c$ - exx - push de ; Recovers b$; A ex hl,hl' would be very handy - exx - pop de ; DE = b$ + inc bc + inc bc ; BC = BC + 2 + ldir ; MEMCOPY: c$ = a$ + pop hl ; HL = c$ + exx + push de ; Recovers b$; A ex hl,hl' would be very handy + exx + pop de ; DE = b$ __STRCAT: ; ConCATenate two strings a$ = a$ + b$. HL = ptr to a$, DE = ptr to b$ - ; NOTE: Both DE, BC and AF are modified and lost - ; Returns HL (pointer to a$) - ; a$ Must be NOT NULL - ld a, d - or e - ret z ; Returns if de is NULL (nothing to copy) - push hl ; Saves HL to return it later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - add hl, bc ; HL = end of (a$) string ; bc = len(a$) - push bc ; Saves LEN(a$) for later - ex de, hl ; DE = end of string (Begin of copy addr) - ld c, (hl) - inc hl - ld b, (hl) ; BC = len(b$) - ld a, b - or c - jr z, __STRCATEND; Return if len(b$) == 0 - push bc ; Save LEN(b$) - inc hl ; Skip 2nd byte of len(b$) - ldir ; Concatenate b$ - pop bc ; Recovers length (b$) - pop hl ; Recovers length (a$) - add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) - ex de, hl ; DE = LEN(a$+b$) - pop hl - ld (hl), e ; Updates new LEN and return - inc hl - ld (hl), d - dec hl - ret + ; NOTE: Both DE, BC and AF are modified and lost + ; Returns HL (pointer to a$) + ; a$ Must be NOT NULL + ld a, d + or e + ret z ; Returns if de is NULL (nothing to copy) + push hl ; Saves HL to return it later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + add hl, bc ; HL = end of (a$) string ; bc = len(a$) + push bc ; Saves LEN(a$) for later + ex de, hl ; DE = end of string (Begin of copy addr) + ld c, (hl) + inc hl + ld b, (hl) ; BC = len(b$) + ld a, b + or c + jr z, __STRCATEND; Return if len(b$) == 0 + push bc ; Save LEN(b$) + inc hl ; Skip 2nd byte of len(b$) + ldir ; Concatenate b$ + pop bc ; Recovers length (b$) + pop hl ; Recovers length (a$) + add hl, bc ; HL = LEN(a$) + LEN(b$) = LEN(a$+b$) + ex de, hl ; DE = LEN(a$+b$) + pop hl + ld (hl), e ; Updates new LEN and return + inc hl + ld (hl), d + dec hl + ret __STRCATEND: - pop hl ; Removes Len(a$) - pop hl ; Restores original HL, so HL = a$ - ret - ENDP + pop hl ; Removes Len(a$) + pop hl ; Restores original HL, so HL = a$ + ret + ENDP + pop namespace #line 36 "valcrash2.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/val.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/free.asm" @@ -609,105 +623,108 @@ __STRCATEND: ; HL = Pointer to the block to be freed. If HL is NULL (0) nothing ; is done ; --------------------------------------------------------------------- + push namespace core MEM_FREE: __MEM_FREE: ; Frees the block pointed by HL - ; HL DE BC & AF modified - PROC - LOCAL __MEM_LOOP2 - LOCAL __MEM_LINK_PREV - LOCAL __MEM_JOIN_TEST - LOCAL __MEM_BLOCK_JOIN - ld a, h - or l - ret z ; Return if NULL pointer - dec hl - dec hl - ld b, h - ld c, l ; BC = Block pointer - ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start + ; HL DE BC & AF modified + PROC + LOCAL __MEM_LOOP2 + LOCAL __MEM_LINK_PREV + LOCAL __MEM_JOIN_TEST + LOCAL __MEM_BLOCK_JOIN + ld a, h + or l + ret z ; Return if NULL pointer + dec hl + dec hl + ld b, h + ld c, l ; BC = Block pointer + ld hl, ZXBASIC_MEM_HEAP ; This label point to the heap start __MEM_LOOP2: - inc hl - inc hl ; Next block ptr - ld e, (hl) - inc hl - ld d, (hl) ; Block next ptr - ex de, hl ; DE = &(block->next); HL = block->next - ld a, h ; HL == NULL? - or l - jp z, __MEM_LINK_PREV; if so, link with previous - or a ; Clear carry flag - sbc hl, bc ; Carry if BC > HL => This block if before - add hl, bc ; Restores HL, preserving Carry flag - jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block + inc hl + inc hl ; Next block ptr + ld e, (hl) + inc hl + ld d, (hl) ; Block next ptr + ex de, hl ; DE = &(block->next); HL = block->next + ld a, h ; HL == NULL? + or l + jp z, __MEM_LINK_PREV; if so, link with previous + or a ; Clear carry flag + sbc hl, bc ; Carry if BC > HL => This block if before + add hl, bc ; Restores HL, preserving Carry flag + jp c, __MEM_LOOP2 ; This block is before. Keep searching PASS the block ;------ At this point current HL is PAST BC, so we must link (DE) with BC, and HL in BC->next __MEM_LINK_PREV: ; Link (DE) with BC, and BC->next with HL - ex de, hl - push hl - dec hl - ld (hl), c - inc hl - ld (hl), b ; (DE) <- BC - ld h, b ; HL <- BC (Free block ptr) - ld l, c - inc hl ; Skip block length (2 bytes) - inc hl - ld (hl), e ; Block->next = DE - inc hl - ld (hl), d - ; --- LINKED ; HL = &(BC->next) + 2 - call __MEM_JOIN_TEST - pop hl + ex de, hl + push hl + dec hl + ld (hl), c + inc hl + ld (hl), b ; (DE) <- BC + ld h, b ; HL <- BC (Free block ptr) + ld l, c + inc hl ; Skip block length (2 bytes) + inc hl + ld (hl), e ; Block->next = DE + inc hl + ld (hl), d + ; --- LINKED ; HL = &(BC->next) + 2 + call __MEM_JOIN_TEST + pop hl __MEM_JOIN_TEST: ; Checks for fragmented contiguous blocks and joins them - ; hl = Ptr to current block + 2 - ld d, (hl) - dec hl - ld e, (hl) - dec hl - ld b, (hl) ; Loads block length into BC - dec hl - ld c, (hl) ; - push hl ; Saves it for later - add hl, bc ; Adds its length. If HL == DE now, it must be joined - or a - sbc hl, de ; If Z, then HL == DE => We must join - pop hl - ret nz + ; hl = Ptr to current block + 2 + ld d, (hl) + dec hl + ld e, (hl) + dec hl + ld b, (hl) ; Loads block length into BC + dec hl + ld c, (hl) ; + push hl ; Saves it for later + add hl, bc ; Adds its length. If HL == DE now, it must be joined + or a + sbc hl, de ; If Z, then HL == DE => We must join + pop hl + ret nz __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed by DE). HL->length already in BC - push hl ; Saves it for later - ex de, hl - ld e, (hl) ; DE -> block->next->length - inc hl - ld d, (hl) - inc hl - ex de, hl ; DE = &(block->next) - add hl, bc ; HL = Total Length - ld b, h - ld c, l ; BC = Total Length - ex de, hl - ld e, (hl) - inc hl - ld d, (hl) ; DE = block->next - pop hl ; Recovers Pointer to block - ld (hl), c - inc hl - ld (hl), b ; Length Saved - inc hl - ld (hl), e - inc hl - ld (hl), d ; Next saved - ret - ENDP + push hl ; Saves it for later + ex de, hl + ld e, (hl) ; DE -> block->next->length + inc hl + ld d, (hl) + inc hl + ex de, hl ; DE = &(block->next) + add hl, bc ; HL = Total Length + ld b, h + ld c, l ; BC = Total Length + ex de, hl + ld e, (hl) + inc hl + ld d, (hl) ; DE = block->next + pop hl ; Recovers Pointer to block + ld (hl), c + inc hl + ld (hl), b ; Length Saved + inc hl + ld (hl), e + inc hl + ld (hl), d ; Next saved + ret + ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/val.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -722,33 +739,35 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/val.asm" + push namespace core VAL: ; Computes VAL(a$) using ROM FP-CALC - ; HL = address of a$ - ; Returns FP number in C ED LH registers - ; A Register = 1 => Free a$ on return - PROC - LOCAL STK_STO_S - LOCAL __RET_ZERO - LOCAL ERR_SP - LOCAL STKBOT - LOCAL RECLAIM1 + ; HL = address of a$ + ; Returns FP number in C ED LH registers + ; A Register = 1 => Free a$ on return + PROC + LOCAL STK_STO_S + LOCAL __RET_ZERO + LOCAL ERR_SP + LOCAL STKBOT + LOCAL RECLAIM1 LOCAL CH_ADD - LOCAL __VAL_ERROR - LOCAL __VAL_EMPTY + LOCAL __VAL_ERROR + LOCAL __VAL_EMPTY LOCAL SET_MIN RECLAIM1 EQU 6629 STKBOT EQU 23651 @@ -757,72 +776,73 @@ VAL: ; Computes VAL(a$) using ROM FP-CALC STK_STO_S EQU 2AB2h SET_MIN EQU 16B0h ld d, a ; Preserves A register in DE - ld a, h - or l - jr z, __RET_ZERO ; NULL STRING => Return 0 + ld a, h + or l + jr z, __RET_ZERO ; NULL STRING => Return 0 push de ; Saves A Register (now in D) - push hl ; Not null string. Save its address for later - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld a, b - or c - jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string - ex de, hl ; DE = String start + push hl ; Not null string. Save its address for later + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld a, b + or c + jr z, __VAL_EMPTY ; Jumps VAL_EMPTY on empty string + ex de, hl ; DE = String start ld hl, (CH_ADD) push hl - ld hl, (STKBOT) - push hl - ld hl, (ERR_SP) - push hl + ld hl, (STKBOT) + push hl + ld hl, (ERR_SP) + push hl ;; Now put our error handler on ERR_SP - ld hl, __VAL_ERROR - push hl - ld hl, 0 - add hl, sp - ld (ERR_SP), hl - call STK_STO_S ; Enter it on the stack - ld b, 1Dh ; "VAL" - rst 28h ; ROM CALC - defb 1Dh ; VAL - defb 38h ; END CALC - pop hl ; Discards our current error handler - pop hl - ld (ERR_SP), hl ; Restores ERR_SP - pop de ; old STKBOT - ld hl, (STKBOT) ; current SKTBOT - call RECLAIM1 ; Recover unused space + ld hl, __VAL_ERROR + push hl + ld hl, 0 + add hl, sp + ld (ERR_SP), hl + call STK_STO_S ; Enter it on the stack + ld b, 1Dh ; "VAL" + rst 28h ; ROM CALC + defb 1Dh ; VAL + defb 38h ; END CALC + pop hl ; Discards our current error handler + pop hl + ld (ERR_SP), hl ; Restores ERR_SP + pop de ; old STKBOT + ld hl, (STKBOT) ; current SKTBOT + call RECLAIM1 ; Recover unused space pop hl ; Discards old CH_ADD value - pop hl ; String pointer - pop af ; Deletion flag - or a - call nz, __MEM_FREE ; Frees string content before returning + pop hl ; String pointer + pop af ; Deletion flag + or a + call nz, __MEM_FREE ; Frees string content before returning ld a, ERROR_Ok ; Sets OK in the result ld (ERR_NR), a - jp __FPSTACK_POP ; Recovers result and return from there + jp __FPSTACK_POP ; Recovers result and return from there __VAL_ERROR: ; Jumps here on ERROR - pop hl - ld (ERR_SP), hl ; Restores ERR_SP - ld hl, (STKBOT) ; current SKTBOT - pop de ; old STKBOT + pop hl + ld (ERR_SP), hl ; Restores ERR_SP + ld hl, (STKBOT) ; current SKTBOT + pop de ; old STKBOT pop hl ld (CH_ADD), hl ; Recovers old CH_ADD call 16B0h ; Resets temporary areas after an error __VAL_EMPTY: ; Jumps here on empty string - pop hl ; Recovers initial string address - pop af ; String flag: If not 0 => it's temporary - or a - call nz, __MEM_FREE ; Frees "" string + pop hl ; Recovers initial string address + pop af ; String flag: If not 0 => it's temporary + or a + call nz, __MEM_FREE ; Frees "" string __RET_ZERO: ; Returns 0 Floating point on error - ld a, ERROR_InvalidArg - ld (ERR_NR), a - xor a - ld b, a - ld c, a - ld d, b - ld e, c - ret - ENDP + ld a, ERROR_InvalidArg + ld (ERR_NR), a + xor a + ld b, a + ld c, a + ld d, b + ld e, c + ret + ENDP + pop namespace #line 37 "valcrash2.bas" END diff --git a/tests/functional/while.asm b/tests/functional/while.asm index eddc8cf98..64acf44e8 100644 --- a/tests/functional/while.asm +++ b/tests/functional/while.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,28 +8,28 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00, 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL__10: __LABEL0: ld hl, _a + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 000h ld de, 00000h ld bc, 00000h - call __LTF + call core.__LTF or a jp z, __LABEL1 __LABEL__20: @@ -38,11 +38,11 @@ __LABEL1: __LABEL__30: __LABEL2: ld hl, _a + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 000h ld de, 00000h ld bc, 00000h - call __LTF + call core.__LTF or a jp z, __LABEL3 __LABEL__40: @@ -53,146 +53,151 @@ __LABEL3: #line 1 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -209,22 +214,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -239,19 +246,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/ltf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -261,21 +269,24 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __LTF: ; A < B - call __FPSTACK_PUSH2 ; Enters B, A - ; ------------- ROM NOS-LESS - ld b, 0Ch ; A > B (Operands stack-reversed) - rst 28h - defb 0Ch; ; A > B - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 ; Enters B, A + ; ------------- ROM NOS-LESS + ld b, 0Ch ; A > B (Operands stack-reversed) + rst 28h + defb 0Ch; ; A > B + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 30 "while.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -296,5 +307,6 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 31 "while.bas" END diff --git a/tests/functional/whileempty1.asm b/tests/functional/whileempty1.asm index 135537ff2..b02b2b631 100644 --- a/tests/functional/whileempty1.asm +++ b/tests/functional/whileempty1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,33 +8,33 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: ld h, 5 ld a, (_i) - call __LTI8 + call core.__LTI8 or a jp nz, __LABEL0 __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -46,8 +46,9 @@ __END_PROGRAM: ;; --- end of user code --- #line 1 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/lei8.asm" + push namespace core __LEI8: ; Signed <= comparison for 8bit int - ; A <= H (registers) + ; A <= H (registers) PROC LOCAL checkParity sub h @@ -65,6 +66,7 @@ checkParity: inc a ; True ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/lti8.asm" #line 24 "whileempty1.bas" END diff --git a/tests/functional/whilefalse.asm b/tests/functional/whilefalse.asm index e7d108ebd..bfac4125e 100644 --- a/tests/functional/whilefalse.asm +++ b/tests/functional/whilefalse.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,26 +8,26 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/whilefalse1.asm b/tests/functional/whilefalse1.asm index 4f073176c..275b82b1e 100644 --- a/tests/functional/whilefalse1.asm +++ b/tests/functional/whilefalse1.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: jp __LABEL1 __LABEL__BAD: diff --git a/tests/functional/whilesplitted.asm b/tests/functional/whilesplitted.asm index eab008a36..b902de528 100644 --- a/tests/functional/whilesplitted.asm +++ b/tests/functional/whilesplitted.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _i: DEFB 00, 00, 00, 00, 00 _M: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: ld hl, _i + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp z, __LABEL1 xor a @@ -39,11 +39,11 @@ __LABEL0: __LABEL1: __LABEL2: ld hl, _i + 4 - call __FP_PUSH_REV + call core.__FP_PUSH_REV ld a, 081h ld de, 00000h ld bc, 00000h - call __EQF + call core.__EQF or a jp z, __LABEL3 xor a @@ -53,9 +53,9 @@ __LABEL3: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -68,146 +68,151 @@ __END_PROGRAM: #line 1 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/neg32.asm" + push namespace core __ABS32: - bit 7, d - ret z + bit 7, d + ret z __NEG32: ; Negates DEHL (Two's complement) - ld a, l - cpl - ld l, a - ld a, h - cpl - ld h, a - ld a, e - cpl - ld e, a - ld a, d - cpl - ld d, a - inc l - ret nz - inc h - ret nz - inc de - ret + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/u32tofreg.asm" + push namespace core __I8TOFREG: - ld l, a - rlca - sbc a, a ; A = SGN(A) - ld h, a - ld e, a - ld d, a + ld l, a + rlca + sbc a, a ; A = SGN(A) + ld h, a + ld e, a + ld d, a __I32TOFREG: ; Converts a 32bit signed integer (stored in DEHL) - ; to a Floating Point Number returned in (A ED CB) - ld a, d - or a ; Test sign - jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned - call __NEG32 ; Convert it to positive - call __U32TOFREG ; Convert it to Floating point - set 7, e ; Put the sign bit (negative) in the 31bit of mantissa - ret + ; to a Floating Point Number returned in (A ED CB) + ld a, d + or a ; Test sign + jp p, __U32TOFREG ; It was positive, proceed as 32bit unsigned + call __NEG32 ; Convert it to positive + call __U32TOFREG ; Convert it to Floating point + set 7, e ; Put the sign bit (negative) in the 31bit of mantissa + ret __U8TOFREG: - ; Converts an unsigned 8 bit (A) to Floating point - ld l, a - ld h, 0 - ld e, h - ld d, h + ; Converts an unsigned 8 bit (A) to Floating point + ld l, a + ld h, 0 + ld e, h + ld d, h __U32TOFREG: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in A ED CB + ; to a Floating point number returned in A ED CB PROC LOCAL __U32TOFREG_END - ld a, d - or e - or h - or l + ld a, d + or e + or h + or l ld b, d - ld c, e ; Returns 00 0000 0000 if ZERO - ret z - push de - push hl - exx - pop de ; Loads integer into B'C' D'E' - pop bc - exx - ld l, 128 ; Exponent - ld bc, 0 ; DEBC = 0 - ld d, b - ld e, c + ld c, e ; Returns 00 0000 0000 if ZERO + ret z + push de + push hl + exx + pop de ; Loads integer into B'C' D'E' + pop bc + exx + ld l, 128 ; Exponent + ld bc, 0 ; DEBC = 0 + ld d, b + ld e, c __U32TOFREG_LOOP: ; Also an entry point for __F16TOFREG - exx - ld a, d ; B'C'D'E' == 0 ? - or e - or b - or c - jp z, __U32TOFREG_END ; We are done - srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry - rr c - rr d - rr e - exx - rr e ; Shift EDCB >> 1, inserting the carry on the left - rr d - rr c - rr b - inc l ; Increment exponent - jp __U32TOFREG_LOOP + exx + ld a, d ; B'C'D'E' == 0 ? + or e + or b + or c + jp z, __U32TOFREG_END ; We are done + srl b ; Shift B'C' D'E' >> 1, output bit stays in Carry + rr c + rr d + rr e + exx + rr e ; Shift EDCB >> 1, inserting the carry on the left + rr d + rr c + rr b + inc l ; Increment exponent + jp __U32TOFREG_LOOP __U32TOFREG_END: - exx + exx ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret + res 7, e ; Sets the sign bit to 0 (positive) + ret ENDP + pop namespace #line 2 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" + push namespace core __FTOU32REG: ; Converts a Float to (un)signed 32 bit integer (NOTE: It's ALWAYS 32 bit signed) - ; Input FP number in A EDCB (A exponent, EDCB mantissa) - ; Output: DEHL 32 bit number (signed) - PROC - LOCAL __IS_FLOAT - LOCAL __NEGATE - or a - jr nz, __IS_FLOAT - ; Here if it is a ZX ROM Integer - ld h, c - ld l, d - ld d, e - ret + ; Input FP number in A EDCB (A exponent, EDCB mantissa) + ; Output: DEHL 32 bit number (signed) + PROC + LOCAL __IS_FLOAT + LOCAL __NEGATE + or a + jr nz, __IS_FLOAT + ; Here if it is a ZX ROM Integer + ld h, c + ld l, d + ld d, e + ret __IS_FLOAT: ; Jumps here if it is a true floating point number - ld h, e - push hl ; Stores it for later (Contains Sign in H) - push de - push bc - exx - pop de ; Loads mantissa into C'B' E'D' - pop bc ; - set 7, c ; Highest mantissa bit is always 1 - exx - ld hl, 0 ; DEHL = 0 - ld d, h - ld e, l - ;ld a, c ; Get exponent - sub 128 ; Exponent -= 128 - jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) - jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) - ld b, a ; Loop counter = exponent - 128 + ld h, e + push hl ; Stores it for later (Contains Sign in H) + push de + push bc + exx + pop de ; Loads mantissa into C'B' E'D' + pop bc ; + set 7, c ; Highest mantissa bit is always 1 + exx + ld hl, 0 ; DEHL = 0 + ld d, h + ld e, l + ;ld a, c ; Get exponent + sub 128 ; Exponent -= 128 + jr z, __FTOU32REG_END ; If it was <= 128, we are done (Integers must be > 128) + jr c, __FTOU32REG_END ; It was decimal (0.xxx). We are done (return 0) + ld b, a ; Loop counter = exponent - 128 __FTOU32REG_LOOP: - exx ; Shift C'B' E'D' << 1, output bit stays in Carry - sla d - rl e - rl b - rl c + exx ; Shift C'B' E'D' << 1, output bit stays in Carry + sla d + rl e + rl b + rl c exx ; Shift DEHL << 1, inserting the carry on the right - rl l - rl h - rl e - rl d - djnz __FTOU32REG_LOOP + rl l + rl h + rl e + rl d + djnz __FTOU32REG_LOOP __FTOU32REG_END: - pop af ; Take the sign bit - or a ; Sets SGN bit to 1 if negative - jp m, __NEGATE ; Negates DEHL - ret + pop af ; Take the sign bit + or a ; Sets SGN bit to 1 if negative + jp m, __NEGATE ; Negates DEHL + ret __NEGATE: exx ld a, d @@ -224,22 +229,24 @@ __NEGATE: LOCAL __END __END: jp __NEG32 - ENDP + ENDP __FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret + call __FTOU32REG + ld a, l + ret + pop namespace #line 3 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" #line 1 "/zxbasic/src/arch/zx48k/library-asm/stackf.asm" ; ------------------------------------------------------------- ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC ; ------------------------------------------------------------- + push namespace core __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) - ; Second argument to push into the stack calculator is popped out of the stack - ; Since the caller routine also receives the parameters into the top of the stack - ; four bytes must be removed from SP before pop them out + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK exx pop hl ; Caller-Caller return addr @@ -254,19 +261,20 @@ __FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP exx jp __FPSTACK_PUSH __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK - ; This format is specified in the ZX 48K Manual - ; You can push a 16 bit signed integer as - ; 0 SS LL HH 0, being SS the sign and LL HH the low - ; and High byte respectively - ld a, h - rla ; sign to Carry - sbc a, a ; 0 if positive, FF if negative - ld e, a - ld d, l - ld c, h - xor a - ld b, a - jp __FPSTACK_PUSH + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/eqf.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) @@ -276,21 +284,24 @@ __FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK ; ; Uses CALLEE convention ; ------------------------------------------------------------- + push namespace core __EQF: ; A = B - call __FPSTACK_PUSH2 - ; ------------- ROM NOS-EQL - ld b, 0Eh ; For comparison operators, OP must be in B also - rst 28h - defb 0Eh - defb 38h; ; END CALC - call __FPSTACK_POP - jp __FTOU8 ; Convert to 8 bits + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace #line 43 "whilesplitted.bas" #line 1 "/zxbasic/src/arch/zx48k/library-asm/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last ; byte of the FP number. ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core __FP_PUSH_REV: push hl exx @@ -311,5 +322,6 @@ __FP_PUSH_REV: push bc ; Return Address exx ret + pop namespace #line 44 "whilesplitted.bas" END diff --git a/tests/functional/whiletrue.asm b/tests/functional/whiletrue.asm index 17f0dc468..6eef72544 100644 --- a/tests/functional/whiletrue.asm +++ b/tests/functional/whiletrue.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,20 +8,20 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: __LABEL0: ld hl, _a inc (hl) @@ -30,9 +30,9 @@ __LABEL1: ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl diff --git a/tests/functional/xor16.asm b/tests/functional/xor16.asm index f39b5e6fc..3967a44fd 100644 --- a/tests/functional/xor16.asm +++ b/tests/functional/xor16.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a) ld a, h or l @@ -46,14 +46,14 @@ __MAIN_PROGRAM__: ld (_b), a ld de, (_a) ld hl, (_a) - call __XOR16 + call core.__XOR16 ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -71,12 +71,13 @@ __END_PROGRAM: ; result in Accumulator (0 False, not 0 True) ; __FASTCALL__ version (operands: A, H) ; Performs 8bit xor 8bit and returns the boolean + push namespace core __XOR16: - ld a, h - or l + ld a, h + or l ld h, a - ld a, d - or e + ld a, d + or e __XOR8: sub 1 sbc a, a @@ -86,6 +87,7 @@ __XOR8: sbc a, a ; a = 00h or FFh xor l ret + pop namespace #line 4 "/zxbasic/src/arch/zx48k/library-asm/xor16.asm" #line 41 "xor16.bas" END diff --git a/tests/functional/xor32.asm b/tests/functional/xor32.asm index e48932e91..23255abfd 100644 --- a/tests/functional/xor32.asm +++ b/tests/functional/xor32.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,29 +8,29 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00, 00, 00, 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld hl, (_a + 2) push hl ld hl, (_a) push hl ld de, 0 ld hl, 0 - call __XOR32 + call core.__XOR32 ld (_b), a ld hl, (_a + 2) push hl @@ -38,7 +38,7 @@ __MAIN_PROGRAM__: push hl ld de, 0 ld hl, 1 - call __XOR32 + call core.__XOR32 ld (_b), a ld hl, (_a) ld de, (_a + 2) @@ -46,7 +46,7 @@ __MAIN_PROGRAM__: push bc ld bc, 0 push bc - call __XOR32 + call core.__XOR32 ld (_b), a ld hl, (_a) ld de, (_a + 2) @@ -54,7 +54,7 @@ __MAIN_PROGRAM__: push bc ld bc, 1 push bc - call __XOR32 + call core.__XOR32 ld (_b), a ld hl, (_a + 2) push hl @@ -62,14 +62,14 @@ __MAIN_PROGRAM__: push hl ld hl, (_a) ld de, (_a + 2) - call __XOR32 + call core.__XOR32 ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -90,12 +90,13 @@ __END_PROGRAM: ; result in Accumulator (0 False, not 0 True) ; __FASTCALL__ version (operands: A, H) ; Performs 8bit xor 8bit and returns the boolean + push namespace core __XOR16: - ld a, h - or l + ld a, h + or l ld h, a - ld a, d - or e + ld a, d + or e __XOR8: sub 1 sbc a, a @@ -105,7 +106,9 @@ __XOR8: sbc a, a ; a = 00h or FFh xor l ret + pop namespace #line 7 "/zxbasic/src/arch/zx48k/library-asm/xor32.asm" + push namespace core __XOR32: ld a, h or l @@ -121,5 +124,6 @@ __XOR32: or e ld h, c jp __XOR8 + pop namespace #line 57 "xor32.bas" END diff --git a/tests/functional/xor8.asm b/tests/functional/xor8.asm index e80a330f6..eceac35ec 100644 --- a/tests/functional/xor8.asm +++ b/tests/functional/xor8.asm @@ -1,5 +1,5 @@ org 32768 -__START_PROGRAM: +core.__START_PROGRAM: di push ix push iy @@ -8,22 +8,22 @@ __START_PROGRAM: exx ld hl, 0 add hl, sp - ld (__CALL_BACK__), hl + ld (core.__CALL_BACK__), hl ei - jp __MAIN_PROGRAM__ -__CALL_BACK__: + jp core.__MAIN_PROGRAM__ +core.__CALL_BACK__: DEFW 0 -ZXBASIC_USER_DATA: +core.ZXBASIC_USER_DATA: ; Defines USER DATA Length in bytes -ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA - .__LABEL__.ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_LEN - .__LABEL__.ZXBASIC_USER_DATA EQU ZXBASIC_USER_DATA +core.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_END - core.ZXBASIC_USER_DATA + core..__LABEL__.ZXBASIC_USER_DATA_LEN EQU core.ZXBASIC_USER_DATA_LEN + core..__LABEL__.ZXBASIC_USER_DATA EQU core.ZXBASIC_USER_DATA _a: DEFB 00 _b: DEFB 00 -ZXBASIC_USER_DATA_END: -__MAIN_PROGRAM__: +core.ZXBASIC_USER_DATA_END: +core.__MAIN_PROGRAM__: ld a, (_a) ld (_b), a ld a, (_a) @@ -38,14 +38,14 @@ __MAIN_PROGRAM__: ld (_b), a ld hl, (_a - 1) ld a, (_a) - call __XOR8 + call core.__XOR8 ld (_b), a ld hl, 0 ld b, h ld c, l -__END_PROGRAM: +core.__END_PROGRAM: di - ld hl, (__CALL_BACK__) + ld hl, (core.__CALL_BACK__) ld sp, hl exx pop hl @@ -61,12 +61,13 @@ __END_PROGRAM: ; result in Accumulator (0 False, not 0 True) ; __FASTCALL__ version (operands: A, H) ; Performs 8bit xor 8bit and returns the boolean + push namespace core __XOR16: - ld a, h - or l + ld a, h + or l ld h, a - ld a, d - or e + ld a, d + or e __XOR8: sub 1 sbc a, a @@ -76,5 +77,6 @@ __XOR8: sbc a, a ; a = 00h or FFh xor l ret + pop namespace #line 33 "xor8.bas" END