diff --git a/src/lib/arch/zx48k/runtime/read_restore.asm b/src/lib/arch/zx48k/runtime/read_restore.asm index da788f40f..2876a97a6 100644 --- a/src/lib/arch/zx48k/runtime/read_restore.asm +++ b/src/lib/arch/zx48k/runtime/read_restore.asm @@ -212,6 +212,13 @@ _from_u16: dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp _i16 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp _f16 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/src/lib/arch/zxnext/runtime/read_restore.asm b/src/lib/arch/zxnext/runtime/read_restore.asm index da788f40f..2876a97a6 100644 --- a/src/lib/arch/zxnext/runtime/read_restore.asm +++ b/src/lib/arch/zxnext/runtime/read_restore.asm @@ -212,6 +212,13 @@ _from_u16: dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp _i16 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp _f16 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/arrbase1.asm b/tests/functional/arch/zx48k/arrbase1.asm index c460df294..bce7b5d9f 100644 --- a/tests/functional/arch/zx48k/arrbase1.asm +++ b/tests/functional/arch/zx48k/arrbase1.asm @@ -107,7 +107,7 @@ __DATA__END: ; O = [a0 + b0 * (a1 + b1 * (a2 + ... bN-2(aN-1)))] ; What I will do here is to calculate the following sequence: ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/mul16.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul16.asm" push namespace core __MUL16: ; Mutiplies HL with the last value stored into de stack ; Works for both signed and unsigned @@ -1217,6 +1217,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/data1.asm b/tests/functional/arch/zx48k/data1.asm index bc0d4e370..451fbf26c 100644 --- a/tests/functional/arch/zx48k/data1.asm +++ b/tests/functional/arch/zx48k/data1.asm @@ -57,7 +57,7 @@ _a: __DATA__END: DEFB 00h ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code ;; Updates the DATA_ADDR read ptr for the next read @@ -75,7 +75,7 @@ __DATA__END: ;; 09: Float ;; bit7 is set for a parameter-less function ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm" ; Simple error control routines ; vim:ts=4:et: push namespace core @@ -109,9 +109,9 @@ __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" +#line 23 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -171,7 +171,7 @@ __STOP: ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -278,7 +278,7 @@ __MEM_INIT2: ret ENDP pop namespace -#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -309,9 +309,9 @@ __MEM_START: __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 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ret z ; NULL -#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; HL = Pointer to Free block ld e, (hl) inc hl @@ -376,7 +376,7 @@ __MEM_SUBTRACT: ret ENDP pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL @@ -413,8 +413,8 @@ __LOADSTR: ; __FASTCALL__ entry 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" +#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL @@ -432,8 +432,8 @@ __ILOAD32: 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" +#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL @@ -460,10 +460,10 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by 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" +#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" push namespace core __ABS32: bit 7, d @@ -488,7 +488,7 @@ __NEG32: ; Negates DEHL (Two's complement) inc de ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -560,7 +560,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -591,9 +591,9 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal 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" +#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" push namespace core __I8TOFREG: ld l, a @@ -663,7 +663,7 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" +#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -698,8 +698,8 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) 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" +#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -857,16 +857,16 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed 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" -#line 33 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 34 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 35 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 36 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; Updates restore point to the given HL mem. address push namespace core __RESTORE: @@ -1026,6 +1026,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' @@ -1146,8 +1153,8 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 32 "data1.bas" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" +#line 32 "arch/zx48k/data1.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 @@ -1175,5 +1182,5 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 33 "data1.bas" +#line 33 "arch/zx48k/data1.bas" END diff --git a/tests/functional/arch/zx48k/opt3_data2.asm b/tests/functional/arch/zx48k/opt3_data2.asm index 4cc2133e0..1dff2e3a4 100644 --- a/tests/functional/arch/zx48k/opt3_data2.asm +++ b/tests/functional/arch/zx48k/opt3_data2.asm @@ -1313,6 +1313,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/read.asm b/tests/functional/arch/zx48k/read.asm index febf55304..3fcb17dce 100644 --- a/tests/functional/arch/zx48k/read.asm +++ b/tests/functional/arch/zx48k/read.asm @@ -73,8 +73,8 @@ __DATA__END: DEFB 61h DEFB 6Eh ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -134,7 +134,7 @@ __DATA__END: ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm" ; Simple error control routines ; vim:ts=4:et: push namespace core @@ -168,8 +168,8 @@ __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" +#line 69 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -276,7 +276,7 @@ __MEM_INIT2: ret ENDP pop namespace -#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -307,9 +307,9 @@ __MEM_START: __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 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ret z ; NULL -#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; HL = Pointer to Free block ld e, (hl) inc hl @@ -374,7 +374,7 @@ __MEM_SUBTRACT: ret ENDP pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL @@ -411,8 +411,8 @@ __LOADSTR: ; __FASTCALL__ entry 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" +#line 48 "arch/zx48k/read.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code ;; Updates the DATA_ADDR read ptr for the next read @@ -430,7 +430,7 @@ __LOADSTR: ; __FASTCALL__ entry ;; 09: Float ;; bit7 is set for a parameter-less function ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/arch/zx48k/library-asm/iload32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL @@ -448,8 +448,8 @@ __ILOAD32: 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" +#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL @@ -476,10 +476,10 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by 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" +#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" push namespace core __ABS32: bit 7, d @@ -504,7 +504,7 @@ __NEG32: ; Negates DEHL (Two's complement) inc de ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -576,7 +576,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -607,9 +607,9 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal 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" +#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" push namespace core __I8TOFREG: ld l, a @@ -679,7 +679,7 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" +#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -714,8 +714,8 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) 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" +#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -873,16 +873,16 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed 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" -#line 33 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 34 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 35 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 36 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; Updates restore point to the given HL mem. address push namespace core __RESTORE: @@ -1042,6 +1042,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' @@ -1162,8 +1169,8 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 49 "read.bas" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" +#line 49 "arch/zx48k/read.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 @@ -1191,5 +1198,5 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 50 "read.bas" +#line 50 "arch/zx48k/read.bas" END diff --git a/tests/functional/arch/zx48k/read12.asm b/tests/functional/arch/zx48k/read12.asm index 1940b79c2..cbd1a4e4f 100644 --- a/tests/functional/arch/zx48k/read12.asm +++ b/tests/functional/arch/zx48k/read12.asm @@ -1324,7 +1324,7 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers __PRINT_DIGIT EQU __PRINTCHAR ; PRINTS the char in A register, and puts its attrs pop namespace #line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div8.asm" ; -------------------------------- push namespace core __DIVU8: ; 8 bit unsigned integer division @@ -2049,6 +2049,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/read13.asm b/tests/functional/arch/zx48k/read13.asm deleted file mode 100644 index 2427b8e67..000000000 --- a/tests/functional/arch/zx48k/read13.asm +++ /dev/null @@ -1,2714 +0,0 @@ - org 32768 -.core.__START_PROGRAM: - di - push ix - push iy - exx - push hl - exx - ld hl, 0 - add hl, sp - ld (.core.__CALL_BACK__), hl - ei - call .core.__MEM_INIT - call .core.__PRINT_INIT - jp .core.__MAIN_PROGRAM__ -.core.__CALL_BACK__: - DEFW 0 -.core.ZXBASIC_USER_DATA: - ; Defines HEAP SIZE -.core.ZXBASIC_HEAP_SIZE EQU 4768 -.core.ZXBASIC_MEM_HEAP: - DEFS 4768 - ; Defines USER DATA Length in bytes -.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_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 - DEFB 01h - DEFB 00h -_i: - DEFB 00 -_c: - DEFW .LABEL.__LABEL5 -_c.__DATA__.__PTR__: - DEFW _c.__DATA__ - DEFW 0 - DEFW 0 -_c.__DATA__: - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h - DEFB 00h -.LABEL.__LABEL5: - DEFW 0000h - DEFB 04h -.core.ZXBASIC_USER_DATA_END: -.core.__MAIN_PROGRAM__: - ld hl, .DATA.__DATA__0 - call .core.__RESTORE - xor a - ld (_i), a - jp .LABEL.__LABEL0 -.LABEL.__LABEL3: - ld a, 8 - call .core.__READ - push de - push hl - ld a, (_i) - ld l, a - ld h, 0 - push hl - ld hl, _c - call .core.__ARRAY - pop bc - pop de - call .core.__STORE32 - call .core.COPY_ATTR - ld a, (_i) - ld l, a - ld h, 0 - push hl - ld hl, _c - call .core.__ARRAY - call .core.__ILOAD32 - call .core.__PRINTF16 - call .core.PRINT_EOL -.LABEL.__LABEL4: - ld hl, _i - inc (hl) -.LABEL.__LABEL0: - ld a, 3 - ld hl, (_i - 1) - cp h - jp nc, .LABEL.__LABEL3 -.LABEL.__LABEL2: - ld hl, 0 - ld b, h - ld c, l -.core.__END_PROGRAM: - di - ld hl, (.core.__CALL_BACK__) - ld sp, hl - exx - pop hl - exx - pop iy - pop ix - ei - ret -___DATA__FUNCPTR__0: - ld hl, (_v) - ld de, (_v + 2) - ld bc, 25 - push bc - ld bc, 0 - push bc - call .core.__MULF16 -___DATA__FUNCPTR__0__leave: - ret -___DATA__FUNCPTR__1: - ld hl, (_v) - ld de, (_v + 2) - call .core.__F16TOFREG - call .core.SIN - push bc - push de - push af - ld hl, (_v) - ld de, (_v + 2) - call .core.__F16TOFREG - call .core.TAN - push bc - push de - push af - ld a, 082h - ld de, 00000h - ld bc, 00000h - call .core.__POW - call .core.__MULF -___DATA__FUNCPTR__1__leave: - ret -___DATA__FUNCPTR__2: - ld hl, (_v) - ld de, (_v + 2) - call .core.__F16TOFREG - ld hl, 0A2DAh - push hl - ld hl, 00F49h - push hl - ld h, 082h - push hl - call .core.__MULF -___DATA__FUNCPTR__2__leave: - ret -.DATA.__DATA__0: - DEFB 3 - DEFB 10 - DEFB 88h - DEFW ___DATA__FUNCPTR__0 - DEFB 89h - DEFW ___DATA__FUNCPTR__1 - DEFB 89h - DEFW ___DATA__FUNCPTR__2 -__DATA__END: - DEFB 00h - ;; --- end of user code --- -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK - exx - pop hl ; Caller-Caller return addr - exx - pop hl ; Caller return addr - pop af - pop de - pop bc - push hl ; Caller return addr - 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 - pop namespace -#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf.asm" - ; ------------------------------------------------------------- - ; Floating point library using the FP ROM Calculator (ZX 48K) - ; All of them uses A EDCB registers as 1st paramter. - ; For binary operators, the 2n operator must be pushed into the - ; stack, in the order A DE BC. - ; - ; Uses CALLEE convention - ; ------------------------------------------------------------- - push namespace core -__MULF: ; Multiplication - call __FPSTACK_PUSH2 - ; ------------- ROM MUL - rst 28h - defb 04h ; - defb 38h; ; END CALC - jp __FPSTACK_POP - pop namespace -#line 111 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" - push namespace core -__ABS32: - 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 - pop namespace -#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_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 -__LMUL: - xor a ; reset carry flag - ld h, a ; result bits 32..47 = 0 - ld l, a - exx - ld h, a ; result bits 48..63 = 0 - ld l, a - 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 -__LMULNOADD: - 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 - pop namespace -#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/arith/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 - ; 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 - pop namespace -#line 112 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/array.asm" -; vim: ts=4:et:sw=4: - ; Copyleft (K) by Jose M. Rodriguez de la Rosa - ; (a.k.a. Boriel) -; http://www.boriel.com - ; ------------------------------------------------------------------- - ; Simple array Index routine - ; Number of total indexes dimensions - 1 at beginning of memory - ; HL = Start of array memory (First two bytes contains N-1 dimensions) - ; Dimension values on the stack, (top of the stack, highest dimension) - ; E.g. A(2, 4) -> PUSH <4>; PUSH <2> - ; For any array of N dimension A(aN-1, ..., a1, a0) - ; and dimensions D[bN-1, ..., b1, b0], the offset is calculated as - ; O = [a0 + b0 * (a1 + b1 * (a2 + ... bN-2(aN-1)))] -; What I will do here is to calculate the following sequence: - ; ((aN-1 * bN-2) + aN-2) * bN-3 + ... -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/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 -__MUL16_FAST: - 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 -__MUL16NOADD: - djnz __MUL16LOOP - ret ; Result in hl (16 lower bits) - ENDP - pop namespace -#line 20 "/zxbasic/src/lib/arch/zx48k/runtime/array.asm" -#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/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 ;; HL <-- [HL] -__ARRAY: - PROC - LOCAL LOOP - LOCAL ARRAY_END - LOCAL TMP_ARR_PTR ; Ptr to Array DATA region. Stored temporarily - LOCAL LBOUND_PTR, UBOUND_PTR ; LBound and UBound PTR indexes - LOCAL RET_ADDR ; Contains the return address popped from the stack - LBOUND_PTR EQU 23698 ; Uses MEMBOT as a temporary variable - UBOUND_PTR EQU LBOUND_PTR + 2 ; Next 2 bytes for UBOUND PTR - RET_ADDR EQU UBOUND_PTR + 2 ; Next 2 bytes for RET_ADDR - TMP_ARR_PTR EQU RET_ADDR + 2 ; Next 2 bytes for TMP_ARR_PTR - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE <-- PTR to Dim sizes table - ld (TMP_ARR_PTR), hl ; HL = Array __DATA__.__PTR__ - inc hl - inc hl - ld c, (hl) - inc hl - ld b, (hl) ; BC <-- Array __LBOUND__ PTR - ld (LBOUND_PTR), bc ; Store it for later -#line 66 "/zxbasic/src/lib/arch/zx48k/runtime/array.asm" - ex de, hl ; HL <-- PTR to Dim sizes table, DE <-- dummy - ex (sp), hl ; Return address in HL, PTR Dim sizes table onto Stack - ld (RET_ADDR), hl ; Stores it for later - exx - pop hl ; Will use H'L' as the pointer to Dim sizes table - ld c, (hl) ; Loads Number of dimensions from (hl) - inc hl - ld b, (hl) - inc hl ; Ready - exx - ld hl, 0 ; HL = Element Offset "accumulator" -LOOP: - ex de, hl ; DE = Element Offset - ld hl, (LBOUND_PTR) - ld a, h - or l - ld b, h - ld c, l - jr z, 1f - ld c, (hl) - inc hl - ld b, (hl) - inc hl - ld (LBOUND_PTR), hl -1: - pop hl ; Get next index (Ai) from the stack - sbc hl, bc ; Subtract LBOUND -#line 116 "/zxbasic/src/lib/arch/zx48k/runtime/array.asm" - add hl, de ; 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 - dec bc ; Decrements loop counter - ld e, (hl) ; Loads next dimension size into D'E' - inc hl - ld d, (hl) - inc hl - push de - exx - pop de ; DE = Max bound Number (i-th dimension) - call __FNMUL ; HL <= HL * DE mod 65536 - jp LOOP -ARRAY_END: - ld a, (hl) - exx -#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/array.asm" - LOCAL ARRAY_SIZE_LOOP - ex de, hl - ld hl, 0 - ld b, a -ARRAY_SIZE_LOOP: - add hl, de - djnz ARRAY_SIZE_LOOP -#line 156 "/zxbasic/src/lib/arch/zx48k/runtime/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 de, (RET_ADDR) - push de - ret - ;; Performs a faster multiply for little 16bit numbs - LOCAL __FNMUL, __FNMUL2 -__FNMUL: - xor a - or h - jp nz, __MUL16_FAST - or l - ret z - cp 33 - jp nc, __MUL16_FAST - ld b, l - ld l, h ; HL = 0 -__FNMUL2: - add hl, de - djnz __FNMUL2 - ret - ENDP - pop namespace -#line 113 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -; vim:ts=4:sw=4:et: - ; PRINT command routine - ; Does not print attribute. Use PRINT_STR or PRINT_NUM for that -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/sysvars.asm" - ;; ----------------------------------------------------------------------- - ;; ZX Basic System Vars - ;; Some of them will be mapped over Sinclair ROM ones for compatibility - ;; ----------------------------------------------------------------------- - push namespace core -SCREEN_ADDR: DW 16384 ; Screen address (can be pointed to other place to use a screen buffer) -SCREEN_ATTR_ADDR: DW 22528 ; Screen attribute address (ditto.) - ; These are mapped onto ZX Spectrum ROM VARS - CHARS EQU 23606 ; Pointer to ROM/RAM Charset - TV_FLAG EQU 23612 ; Flags for controlling output to screen - UDG EQU 23675 ; Pointer to UDG Charset - COORDS EQU 23677 ; Last PLOT coordinates - FLAGS2 EQU 23681 ; - ECHO_E EQU 23682 ; - DFCC EQU 23684 ; Next screen addr for PRINT - DFCCL EQU 23686 ; Next screen attr for PRINT - S_POSN EQU 23688 - ATTR_P EQU 23693 ; Current Permanent ATTRS set with INK, PAPER, etc commands - ATTR_T EQU 23695 ; temporary ATTRIBUTES - P_FLAG EQU 23697 ; - MEM0 EQU 23698 ; Temporary memory buffer used by ROM chars - SCR_COLS EQU 33 ; Screen with in columns + 1 - SCR_ROWS EQU 24 ; Screen height in rows - SCR_SIZE EQU (SCR_ROWS << 8) + SCR_COLS - pop namespace -#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm" - ; Attribute routines -; vim:ts=4:et:sw: -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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: - ; ld a, ERROR_CODE - ; ld (ERR_NR), a - ERROR_Ok EQU -1 - ERROR_SubscriptWrong EQU 2 - ERROR_OutOfMemory EQU 3 - ERROR_OutOfScreen EQU 4 - ERROR_NumberTooBig EQU 5 - ERROR_InvalidArg EQU 9 - ERROR_IntOutOfRange EQU 10 - ERROR_NonsenseInBasic EQU 11 - ERROR_InvalidFileName EQU 14 - ERROR_InvalidColour EQU 19 - ERROR_BreakIntoProgram EQU 20 - ERROR_TapeLoadingErr EQU 26 - ; Raises error using RST #8 -__ERROR: - ld (__ERROR_CODE), a - rst 8 -__ERROR_CODE: - nop - ret - ; Sets the error system variable, but keeps running. - ; Usually this instruction if followed by the END intermediate instruction. -__STOP: - ld (ERR_NR), a - ret - pop namespace -#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/attr.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/in_screen.asm" - push namespace core -__IN_SCREEN: - ; Returns NO carry if current coords (D, E) - ; are OUT of the screen limits - PROC - LOCAL __IN_SCREEN_ERR - ld hl, SCR_SIZE - ld a, e - cp l - jr nc, __IN_SCREEN_ERR ; Do nothing and return if out of range - ld a, d - cp h - ret c ; Return if carry (OK) -__IN_SCREEN_ERR: -__OUT_OF_SCREEN_ERR: - ; Jumps here if out of screen - ld a, ERROR_OutOfScreen - jp __STOP ; Saves error code and exits - ENDP - pop namespace -#line 7 "/zxbasic/src/lib/arch/zx48k/runtime/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 - ld h, 0 ; 7 T-States - ld a, d ; 4 T-States - ld d, h - add a, a ; a * 2 ; 4 T-States - add a, a ; a * 4 ; 4 T-States - ld l, a ; HL = A * 4 ; 4 T-States - 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 - add hl, de - ld de, (SCREEN_ATTR_ADDR) ; Adds the screen address - add hl, de - ; Return current screen address in HL - ret - ; Sets the attribute at a given screen coordinate (D, E). - ; The attribute is taken from the ATTR_T memory variable - ; Used by PRINT routines -SET_ATTR: - ; Checks for valid coords - call __IN_SCREEN - ret nc - call __ATTR_ADDR -__SET_ATTR: - ; Internal __FASTCALL__ Entry used by printing routines - ; HL contains the address of the ATTR cell to set - PROC -__SET_ATTR2: ; Sets attr from ATTR_T to (HL) which points to the scr address - ld de, (ATTR_T) ; E = ATTR_T, D = MASK_T - ld a, d - and (hl) - ld c, a ; C = current screen color, masked - ld a, d - cpl ; Negate mask - and e ; Mask current attributes - or c ; Mix them - ld (hl), a ; Store result in screen - ret - ENDP - pop namespace -#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/sposn.asm" - ; Printing positioning library. - push namespace core - ; Loads into DE current ROW, COL print position from S_POSN mem var. -__LOAD_S_POSN: - PROC - ld de, (S_POSN) - ld hl, SCR_SIZE - or a - sbc hl, de - ex de, hl - ret - ENDP - ; Saves ROW, COL from DE into S_POSN mem var. -__SAVE_S_POSN: - PROC - ld hl, SCR_SIZE - or a - sbc hl, de - ld (S_POSN), hl ; saves it again -__SET_SCR_PTR: ;; Fast - push de - call __ATTR_ADDR - ld (DFCCL), hl - pop de - 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 - ld hl, (SCREEN_ADDR) - add hl, de ; HL = Screen address + DE - ld (DFCC), hl - ret - ENDP - pop namespace -#line 6 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/table_jump.asm" - push namespace core -JUMP_HL_PLUS_2A: ; Does JP (HL + A*2) Modifies DE. Modifies A - add a, a -JUMP_HL_PLUS_A: ; Does JP (HL + A) Modifies DE - 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 -CALL_HL: - jp (hl) - pop namespace -#line 8 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__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 -__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 - ; Sets the INK color passed in A register in the ATTR_T variable -INK_TMP: - ld de, ATTR_T - jp __SET_INK - ENDP - pop namespace -#line 9 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__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 -__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 - ; Sets the PAPER color passed in A register in the ATTR_T variable -PAPER_TMP: - ld de, ATTR_T - jp __SET_PAPER - ENDP - pop namespace -#line 10 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/flash.asm" - ; Sets flash flag in ATTR_P permanently -; Parameter: Paper color in A register - push namespace core -FLASH: - 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 -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 -IS_TR: ; transparent - 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 - ENDP - pop namespace -#line 11 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bright.asm" - ; Sets bright flag in ATTR_P permanently -; Parameter: Paper color in A register - push namespace core -BRIGHT: - 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 -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 -IS_TR: ; transparent - inc hl ; Points DE to MASK_T or MASK_P - set 6, (hl) ;Set bit 6 to enable transparency - ret - ; Sets the BRIGHT flag passed in A register in the ATTR_T variable -BRIGHT_TMP: - ld hl, ATTR_T - jr __SET_BRIGHT - ENDP - pop namespace -#line 12 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - ; 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) - or (hl) - ld (hl), a - jp __SET_ATTR_MODE - ENDP - pop namespace -#line 13 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - ; 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 - pop namespace -#line 14 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - rlca - 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 - pop namespace -#line 15 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - rrca - rrca - rrca - 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 - pop namespace -#line 16 "/zxbasic/src/lib/arch/zx48k/runtime/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 - ;; Clears ATTR2 flags (OVER 2, etc) - xor a - ld (FLAGS2), a - ld hl, TV_FLAG - res 0, (hl) - LOCAL SET_SCR_ADDR - call __LOAD_S_POSN - jp __SET_SCR_PTR - ;; Receives HL = future value of S_POSN - ;; Stores it at (S_POSN) and refresh screen pointers (ATTR, SCR) -SET_SCR_ADDR: - ld (S_POSN), hl - ex de, hl - ld hl, SCR_SIZE - or a - sbc hl, de - ex de, hl - dec e - jp __SET_SCR_PTR -__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_JUMP - LOCAL __SRCADDR - LOCAL __PRINT_UDG - LOCAL __PRGRAPH - LOCAL __PRINT_START - PRINT_JUMP_STATE EQU __PRINT_JUMP + 2 -__PRINT_JUMP: - exx ; Switch to alternative registers - jp __PRINT_START ; Where to jump. If we print 22 (AT), next two calls jumps to AT1 and AT2 respectively -__PRINT_START: -__PRINT_CHR: - cp ' ' - jr c, __PRINT_SPECIAL ; Characters below ' ' are special ones - ex af, af' ; Saves a value (char to print) for later - ld hl, (S_POSN) - dec l - jr nz, 1f - ld l, SCR_COLS - 1 - dec h - jr nz, 2f - inc h - push hl - call __SCROLL_SCR - pop hl -#line 94 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -2: - call SET_SCR_ADDR - jr 4f -1: - ld (S_POSN), hl -4: - ex af, af' - cp 80h ; Is it a "normal" (printable) char - jr c, __SRCADDR - cp 90h ; Is it an UDG? - jr nc, __PRINT_UDG - ; Print an 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) - jr __PRGRAPH0 - __SOURCEADDR EQU (__SRCADDR + 1) ; Address of the pointer to chars source -__SRCADDR: - 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 -__PRGRAPH: - ex de, hl ; HL = Write Address, DE = CHARS address - bit 2, (iy + $47) - call nz, __BOLD -#line 141 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - bit 4, (iy + $47) - call nz, __ITALIC -#line 146 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - ld hl, (DFCC) - push hl - ld b, 8 ; 8 bytes per char -__PRCHAR: - ld a, (de) ; DE *must* be 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 operations: - ; NORMAL : 0h --> NOP ; OVER 0 - ; XOR : AEh --> XOR (HL) ; OVER 1 - ; OR : B6h --> OR (HL) ; PUTSPRITE - ; AND : A6h --> AND (HL) ; PUTMASK - nop ; Set to one of the values above -INVERSE_MODE: ; 00 -> NOP -> INVERSE 0 - nop ; 2F -> CPL -> INVERSE 1 - ld (hl), a - inc de - inc h ; Next line - djnz __PRCHAR - pop hl - inc hl - ld (DFCC), hl - ld hl, (DFCCL) ; current ATTR Pos - inc hl - ld (DFCCL), hl - dec hl - call __SET_ATTR - exx - ret - ; ------------- SPECIAL CHARS (< 32) ----------------- -__PRINT_SPECIAL: ; Jumps here if it is a special char - ld hl, __PRINT_TABLE - jp JUMP_HL_PLUS_2A -PRINT_EOL: ; Called WHENEVER there is no ";" at end of PRINT sentence - exx -__PRINT_0Dh: ; Called WHEN printing CHR$(13) - ld hl, (S_POSN) - dec l - jr nz, 1f - dec h - jr nz, 1f - inc h - push hl - call __SCROLL_SCR - pop hl -#line 211 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -1: - ld l, 1 -__PRINT_EOL_END: - call SET_SCR_ADDR - exx - ret -__PRINT_COM: - 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 -__PRINT_TAB1: - ld (MEM0), a - ld hl, __PRINT_TAB2 - jr __PRINT_SET_STATE -__PRINT_TAB2: - ld a, (MEM0) ; Load tab code (ignore the current one) - ld hl, __PRINT_START - ld (PRINT_JUMP_STATE), hl - exx - push hl - push bc - push de - call PRINT_TAB - pop de - pop bc - pop hl - ret -__PRINT_AT: - ld hl, __PRINT_AT1 - jr __PRINT_SET_STATE -__PRINT_NOP: -__PRINT_RESTART: - ld hl, __PRINT_START -__PRINT_SET_STATE: - ld (PRINT_JUMP_STATE), hl ; Saves next entry call - exx - ret -__PRINT_AT1: ; Jumps here if waiting for 1st parameter - ld hl, (S_POSN) - ld h, a - ld a, SCR_ROWS - sub h - ld (S_POSN + 1), a - ld hl, __PRINT_AT2 - jr __PRINT_SET_STATE -__PRINT_AT2: - call __LOAD_S_POSN - ld e, a - call __SAVE_S_POSN - jr __PRINT_RESTART -__PRINT_DEL: - call __LOAD_S_POSN ; Gets current screen position - dec e - ld a, -1 - cp e - jr nz, 3f - ld e, SCR_COLS - 2 - dec d - cp d - jr nz, 3f - ld d, SCR_ROWS - 1 -3: - call __SAVE_S_POSN - exx - ret -__PRINT_INK: - ld hl, __PRINT_INK2 - jr __PRINT_SET_STATE -__PRINT_INK2: - call INK_TMP - jr __PRINT_RESTART -__PRINT_PAP: - ld hl, __PRINT_PAP2 - jr __PRINT_SET_STATE -__PRINT_PAP2: - call PAPER_TMP - jr __PRINT_RESTART -__PRINT_FLA: - ld hl, __PRINT_FLA2 - jr __PRINT_SET_STATE -__PRINT_FLA2: - call FLASH_TMP - jr __PRINT_RESTART -__PRINT_BRI: - ld hl, __PRINT_BRI2 - jr __PRINT_SET_STATE -__PRINT_BRI2: - call BRIGHT_TMP - jr __PRINT_RESTART -__PRINT_INV: - ld hl, __PRINT_INV2 - jr __PRINT_SET_STATE -__PRINT_INV2: - call INVERSE_TMP - jr __PRINT_RESTART -__PRINT_OVR: - ld hl, __PRINT_OVR2 - jr __PRINT_SET_STATE -__PRINT_OVR2: - call OVER_TMP - jr __PRINT_RESTART -__PRINT_BOLD: - ld hl, __PRINT_BOLD2 - jp __PRINT_SET_STATE -__PRINT_BOLD2: - call BOLD_TMP - jp __PRINT_RESTART -#line 355 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -__PRINT_ITA: - ld hl, __PRINT_ITA2 - jp __PRINT_SET_STATE -__PRINT_ITA2: - call ITALIC_TMP - jp __PRINT_RESTART -#line 365 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - LOCAL __BOLD -__BOLD: - push hl - ld hl, MEM0 - ld b, 8 -1: - ld a, (de) - ld c, a - rlca - or c - ld (hl), a - inc hl - inc de - djnz 1b - pop hl - ld de, MEM0 - ret -#line 386 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - LOCAL __ITALIC -__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 -#line 414 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - LOCAL __SCROLL_SCR -#line 488 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - __SCROLL_SCR EQU 0DFEh ; Use ROM SCROLL -#line 490 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -#line 491 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -PRINT_COMMA: - call __LOAD_S_POSN - ld a, e - and 16 - add a, 16 -PRINT_TAB: - ; Tabulates the number of spaces in A register - ; If the current cursor position is already A, does nothing - PROC - LOCAL LOOP - call __LOAD_S_POSN ; e = current row - sub e - and 31 - ret z - ld b, a -LOOP: - ld a, ' ' - call __PRINTCHAR - 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 - jp __SAVE_S_POSN - LOCAL __PRINT_COM - LOCAL __PRINT_AT1 - LOCAL __PRINT_AT2 - LOCAL __PRINT_BOLD - LOCAL __PRINT_ITA - LOCAL __PRINT_INK - LOCAL __PRINT_PAP - LOCAL __PRINT_SET_STATE - LOCAL __PRINT_TABLE - LOCAL __PRINT_TAB, __PRINT_TAB1, __PRINT_TAB2 - LOCAL __PRINT_ITA2 -#line 547 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" - LOCAL __PRINT_BOLD2 -#line 553 "/zxbasic/src/lib/arch/zx48k/runtime/print.asm" -__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 - pop namespace -#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm" -#line 4 "/zxbasic/src/lib/arch/zx48k/runtime/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 - INVERSE1 EQU 02Fh - 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 -CONT2: - 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 67 "/zxbasic/src/lib/arch/zx48k/runtime/copy_attr.asm" -__REFRESH_TMP: - ld a, (hl) - and 0b10101010 - ld c, a - rra - or c - ld (hl), a - ret - ENDP - pop namespace -#line 114 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__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 -__U8TOFREG: - ; 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 - PROC - LOCAL __U32TOFREG_END - 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 -__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 -__U32TOFREG_END: - exx - ld a, l ; Puts the exponent in a - res 7, e ; Sets the sign bit to 0 (positive) - ret - ENDP - pop namespace -#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) - 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 -__F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) - ; to a Floating point number returned in C DE HL - ld a, d - or e - or h - or l - 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 - ENDP - pop namespace -#line 115 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - pop namespace -#line 116 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" - ; ------------------------------------------------------------- - ; Floating point library using the FP ROM Calculator (ZX 48K) - ; All of them uses A EDCB registers as 1st paramter. - ; For binary operators, the 2n operator must be pushed into the - ; stack, in the order A DE BC. - ; - ; Uses CALLEE convention - ; -; Operands comes swapped: - ; 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 - pop namespace -#line 117 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/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 - pop namespace -#line 118 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/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 - pop namespace -#line 119 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__PRINTU_CONT: - pop af - push bc - call __PRINT_DIGIT - pop bc - djnz __PRINTU_CONT - ret - ENDP -__PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers - 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/lib/arch/zx48k/runtime/printf16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div16.asm" - ; 16 bit division and modulo functions - ; for both signed and unsigned values -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg16.asm" - ; Negates HL value (16 bit) - push namespace core -__ABS16: - 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 - pop namespace -#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div16.asm" - push namespace core -__DIVU16: ; 16 bit unsigned division - ; HL = Dividend, Stack Top = Divisor - ; -- OBSOLETE ; Now uses FASTCALL convention - ; ex de, hl - ; pop hl ; Return address - ; ex (sp), hl ; CALLEE Convention -__DIVU16_FAST: - ld a, h - ld c, l - ld hl, 0 - ld b, 16 -__DIV16LOOP: - sll c - rla - adc hl,hl - sbc hl,de - jr nc, __DIV16NOADD - add hl,de - dec c -__DIV16NOADD: - djnz __DIV16LOOP - ex de, hl - ld h, a - ld l, c - ret ; HL = quotient, DE = Mudulus -__MODU16: ; 16 bit modulus - ; 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 - ret -__DIVI16: ; 16 bit signed division - ; --- 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 -__DIVI16A: - bit 7, h ; HL is negative? - call nz, __NEGHL -__DIVI16B: - call __DIVU16_FAST - ex af, af' - or a - ret p ; return if positive - jp __NEGHL -__MODI16: ; 16 bit modulus - ; 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 - ret - pop namespace -#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__PRINTU16: - 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 - pop namespace -#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__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 -__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 - pop namespace -#line 121 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" - ;; This implements READ & RESTORE functions - ;; Reads a new element from the DATA Address code - ;; Updates the DATA_ADDR read ptr for the next read - ;; Data codification is 1 byte for type followed by data bytes - ;; Byte type is encoded as follows -;; 00: End of data -;; 01: String -;; 02: Byte -;; 03: Ubyte -;; 04: Integer -;; 05: UInteger -;; 06: Long -;; 07: ULong -;; 08: Fixed -;; 09: Float - ;; bit7 is set for a parameter-less function - ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" -; vim: ts=4:et:sw=4: - ; Copyleft (K) by Jose M. Rodriguez de la Rosa - ; (a.k.a. Boriel) -; http://www.boriel.com - ; - ; This ASM library is licensed under the MIT license - ; you can use it for any purpose (even for commercial - ; closed source programs). - ; - ; Please read the MIT license on the internet - ; ----- IMPLEMENTATION NOTES ------ - ; The heap is implemented as a linked list of free blocks. -; Each free block contains this info: - ; - ; +----------------+ <-- 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) |---+ - ; +----------------+ | - ; | | | - ; | (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 | - ; +----------------+ - ; | | - ; | (0 if Size = 4)| - ; +----------------+ - ; When a block is FREED, the previous and next pointers are examined to see - ; if we can defragment the heap. If the block to be freed is just next to the - ; previous, or to the next (or both) they will be converted into a single - ; block (so defragmented). - ; MEMORY MANAGER - ; - ; 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. -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" -; vim: ts=4:et:sw=4: - ; Copyleft (K) by Jose M. Rodriguez de la Rosa - ; (a.k.a. Boriel) -; http://www.boriel.com - ; - ; This ASM library is licensed under the BSD license - ; you can use it for any purpose (even for commercial - ; closed source programs). - ; - ; Please read the BSD license on the internet - ; ----- IMPLEMENTATION NOTES ------ - ; The heap is implemented as a linked list of free blocks. -; Each free block contains this info: - ; - ; +----------------+ <-- 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) |---+ - ; +----------------+ | - ; | | | - ; | (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 | - ; +----------------+ - ; | | - ; | (0 if Size = 4)| - ; +----------------+ - ; When a block is FREED, the previous and next pointers are examined to see - ; if we can defragment the heap. If the block to be breed is just next to the - ; previous, or to the next (or both) they will be converted into a single - ; block (so defragmented). - ; MEMORY MANAGER - ; - ; 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. - ; --------------------------------------------------------------------- - ; __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 - ; --------------------------------------------------------------------- - ; __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 - pop namespace -#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" - ; --------------------------------------------------------------------- - ; MEM_ALLOC - ; Allocates a block of memory in the heap. - ; - ; Parameters - ; BC = Length of requested memory block - ; -; Returns: - ; 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 - TEMP EQU TEMP0 + 1 - 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 -__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 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" - ret z ; NULL -#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" - ; HL = Pointer to Free block - ld e, (hl) - inc hl - ld d, (hl) - inc hl ; DE = Block Length - push hl ; HL = *pointer to -> next block - ex de, hl - or a ; CF = 0 - sbc hl, bc ; FREE >= BC (Length) (HL = BlockLength - Length) - jp nc, __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), 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 - pop namespace -#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__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 - pop namespace -#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 - ld h, (hl) - ld l, a - ; __FASTCALL__ routine which - ; loads a 40 bits floating point into A ED CB - ; 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 - pop namespace -#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 -__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 -__FTOU32REG_LOOP: - 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 -__FTOU32REG_END: - 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 - or e - or b - or c - exx - jr z, __END - inc l - jr nz, __END - inc h - jr nz, __END - inc de - LOCAL __END -__END: - jp __NEG32 - ENDP -__FTOU8: ; Converts float in C ED LH to Unsigned byte in A - call __FTOU32REG - ld a, l - ret - pop namespace -#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) - ld l, a ; Saves exponent for later - 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 - pop bc - 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 - pop namespace -#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" -; vim: ts=4:et:sw=4: - ; Copyleft (K) by Jose M. Rodriguez de la Rosa - ; (a.k.a. Boriel) -; http://www.boriel.com - ; - ; This ASM library is licensed under the BSD license - ; you can use it for any purpose (even for commercial - ; closed source programs). - ; - ; Please read the BSD license on the internet - ; ----- IMPLEMENTATION NOTES ------ - ; The heap is implemented as a linked list of free blocks. -; Each free block contains this info: - ; - ; +----------------+ <-- 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) |---+ - ; +----------------+ | - ; | | | - ; | (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 | - ; +----------------+ - ; | | - ; | (0 if Size = 4)| - ; +----------------+ - ; When a block is FREED, the previous and next pointers are examined to see - ; if we can defragment the heap. If the block to be breed is just next to the - ; previous, or to the next (or both) they will be converted into a single - ; block (so defragmented). - ; MEMORY MANAGER - ; - ; 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. - ; --------------------------------------------------------------------- - ; MEM_FREE - ; Frees a block of memory - ; -; Parameters: - ; 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 -__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 - ;------ 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 -__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 -__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 - pop namespace -#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" -#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" - ;; Updates restore point to the given HL mem. address - push namespace core -__RESTORE: - PROC - LOCAL __DATA_ADDR - ld (__DATA_ADDR), hl - ret - ;; Reads a value from the DATA mem area and updates __DATA_ADDR ptr to the - ;; next item. On Out Of Data, restarts - ;; -__READ: - LOCAL read_restart, cont, cont2, table, no_func - LOCAL dynamic_cast, dynamic_cast2, dynamic_cast3, dynamic_cast4 - LOCAL _decode_table, coerce_to_int, coerce_to_int2, promote_to_i16 - LOCAL _from_i8, _from_u8 - LOCAL _from_i16, _from_u16 - LOCAL _from_i32, _from_u32 - LOCAL _from_fixed, __data_error - push af ; type of data to read - ld hl, (__DATA_ADDR) -read_restart: - ld a, (hl) - or a ; 0 => OUT of data - jr nz, cont - ;; Signals out of data - ld hl, .DATA.__DATA__0 - ld (__DATA_ADDR), hl - jr read_restart ; Start again -cont: - and 0x80 - ld a, (hl) - push af - jp z, no_func ;; Loads data directly, not a function - inc hl - ld e, (hl) - inc hl - ld d, (hl) - inc hl - ld (__DATA_ADDR), hl ;; Store address of next DATA - ex de, hl -cont2: - ld de, dynamic_cast - push de ; ret address - jp (hl) ; "call (hl)" - ;; Now tries to convert the given result to the expected type or raise an error -dynamic_cast: - exx - ex af, af' - pop af ; type READ - and 0x7F ; clear bit 7 - pop hl ; type requested by USER (type of the READ variable) - ld c, h ; save requested type (save it in register C) - cp h - exx - jr nz, dynamic_cast2 ; Types are identical? - ;; yes, they are - ex af, af' - ret -dynamic_cast2: - cp 1 ; Requested a number, but read a string? - jr nz, dynamic_cast3 - call __MEM_FREE ; Frees str from memory - jr __data_error -dynamic_cast3: - exx - ld b, a ; Read type - ld a, c ; Requested type - cp 1 - jr z, __data_error - cp b - jr c, dynamic_cast4 - ;; here the user expected type is "larger" than the read one - ld a, b - sub 2 - add a, a - ld l, a - ld h, 0 - ld de, _decode_table - add hl, de - ld e, (hl) - inc hl - ld h, (hl) - ld l, e - push hl - ld a, c ; Requested type - exx - ret -__data_error: - ;; When a data is read, but cannot be converted to the requested type - ;; that is, the user asked for a string and we read a number or vice versa - ld a, ERROR_InvalidArg - call __STOP ; The user expected a string, but read a number - xor a - ld h, a - ld l, a - ld e, a - ld d, a - ld b, a - ld c, a - ret -_decode_table: - dw _from_i8 - dw _from_u8 - dw _from_i16 - dw _from_u16 - dw _from_i32 - dw _from_u32 - dw _from_fixed -_from_i8: - cp 4 - jr nc, promote_to_i16 - ex af, af' - ret ;; Was from Byte to Ubyte -promote_to_i16: - ex af, af' - ld l, a - rla - sbc a, a - ld h, a ; copy sgn to h - ex af, af' - jr _before_from_i16 -_from_u8: - ex af, af' - ld l, a - ld h, 0 - ex af, af' - ;; Promoted to i16 -_before_from_i16: -_from_i16: - cp 6 - ret c ;; from i16 to u16 - ;; Promote i16 to i32 - ex af, af' - ld a, h - rla - sbc a, a - ld e, a - ld d, a - ex af, af' -_from_i32: - cp 7 - ret z ;; From i32 to u32 - ret c ;; From u16 to i32 - cp 9 - jp z, __I32TOFREG -_from_u32: - cp 9 - jp z, __U32TOFREG - ex de, hl - ld hl, 0 - cp 8 - ret z -_from_fixed: ;; From fixed to float - jp __F16TOFREG -_from_u16: - ld de, 0 ; HL 0x0000 => 32 bits - jp _from_i32 -dynamic_cast4: - ;; The user type is "shorter" than the read one - cp 8 ;; required type - jr c, before_to_int ;; required < fixed (f16) - ex af, af' - exx ;; Ok, we must convert from float to f16 - jp __FTOF16REG -before_to_int: - ld a, b ;; read type - cp 8 ;; - jr c, coerce_to_int2 - jr nz, coerce_to_int ;; From float to int - ld a, c ;; user type - exx - ;; f16 to Long - ex de, hl - ld a, h - rla - sbc a, a - ld d, a - ld e, a - exx - jr coerce_to_int2 -coerce_to_int: - exx - ex af, af' - call __FTOU32REG - ex af, af' ; a contains user type - exx -coerce_to_int2: ; At this point we have an u/integer in hl - exx - cp 4 - ret nc ; Already done. Return the result - ld a, l ; Truncate to byte - ret -no_func: - exx - ld de, dynamic_cast - push de ; Ret address - dec a ; 0 => string; 1, 2 => byte; 3, 4 => integer; 5, 6 => long, 7 => fixed; 8 => float - ld h, 0 - add a, a - ld l, a - ld de, table - add hl, de - ld e, (hl) - inc hl - ld h, (hl) - ld l, e - push hl ; address to jump to - exx - inc hl - ret ; jp (sp) => jump to table[a - 1] -table: - LOCAL __01_decode_string - LOCAL __02_decode_byte - LOCAL __03_decode_ubyte - LOCAL __04_decode_integer - LOCAL __05_decode_uinteger - LOCAL __06_decode_long - LOCAL __07_decode_ulong - LOCAL __08_decode_fixed - LOCAL __09_decode_float - ;; 1 -> Decode string - ;; 2, 3 -> Decode Byte, UByte - ;; 4, 5 -> Decode Integer, UInteger - ;; 6, 7 -> Decode Long, ULong - ;; 8 -> Decode Fixed - ;; 9 -> Decode Float - dw __01_decode_string - dw __02_decode_byte - dw __03_decode_ubyte - dw __04_decode_integer - dw __05_decode_uinteger - dw __06_decode_long - dw __07_decode_ulong - dw __08_decode_fixed - dw __09_decode_float -__01_decode_string: - ld e, (hl) - inc hl - ld d, (hl) - inc hl - 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) - inc hl - ld d, (hl) - inc hl - ld (__DATA_ADDR), hl - ex de, hl - ret -__06_decode_long: -__07_decode_ulong: -__08_decode_fixed: - ld b, h - ld c, l - inc bc - inc bc - inc bc - inc bc - ld (__DATA_ADDR), bc - jp __ILOAD32 -__09_decode_float: - call __LOADF - inc hl - ld (__DATA_ADDR), hl - ld h, a ; returns A in H; sets A free - ret -__DATA_ADDR: ;; Stores current DATA ptr - dw .DATA.__DATA__0 - ENDP - pop namespace -#line 122 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/store32.asm" - push namespace core -__PISTORE32: - 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 -__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 - pop namespace -#line 123 "arch/zx48k/read13.bas" - END diff --git a/tests/functional/arch/zx48k/read14.asm b/tests/functional/arch/zx48k/read14.asm index ccb3166a9..d4d43a497 100644 --- a/tests/functional/arch/zx48k/read14.asm +++ b/tests/functional/arch/zx48k/read14.asm @@ -50,7 +50,7 @@ _j: __DATA__END: DEFB 00h ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code ;; Updates the DATA_ADDR read ptr for the next read @@ -68,7 +68,7 @@ __DATA__END: ;; 09: Float ;; bit7 is set for a parameter-less function ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm" ; Simple error control routines ; vim:ts=4:et: push namespace core @@ -102,9 +102,9 @@ __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" +#line 23 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -164,7 +164,7 @@ __STOP: ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -271,7 +271,7 @@ __MEM_INIT2: ret ENDP pop namespace -#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -302,9 +302,9 @@ __MEM_START: __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 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ret z ; NULL -#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; HL = Pointer to Free block ld e, (hl) inc hl @@ -369,7 +369,7 @@ __MEM_SUBTRACT: ret ENDP pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL @@ -406,8 +406,8 @@ __LOADSTR: ; __FASTCALL__ entry 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" +#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL @@ -425,8 +425,8 @@ __ILOAD32: 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" +#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL @@ -453,10 +453,10 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by 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" +#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" push namespace core __ABS32: bit 7, d @@ -481,7 +481,7 @@ __NEG32: ; Negates DEHL (Two's complement) inc de ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -553,7 +553,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -584,9 +584,9 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal 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" +#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" push namespace core __I8TOFREG: ld l, a @@ -656,7 +656,7 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" +#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -691,8 +691,8 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) 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" +#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -850,16 +850,16 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed 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" -#line 33 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 34 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 35 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 36 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; Updates restore point to the given HL mem. address push namespace core __RESTORE: @@ -1019,6 +1019,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' @@ -1139,5 +1146,5 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 25 "read14.bas" +#line 25 "arch/zx48k/read14.bas" END diff --git a/tests/functional/arch/zx48k/read4.asm b/tests/functional/arch/zx48k/read4.asm index 72d4d2b52..a7ebf2aa9 100644 --- a/tests/functional/arch/zx48k/read4.asm +++ b/tests/functional/arch/zx48k/read4.asm @@ -1255,6 +1255,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/read8.asm b/tests/functional/arch/zx48k/read8.asm index 64f563a16..46943918e 100644 --- a/tests/functional/arch/zx48k/read8.asm +++ b/tests/functional/arch/zx48k/read8.asm @@ -2191,6 +2191,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/read9.asm b/tests/functional/arch/zx48k/read9.asm index 254b8460d..0a4b91be2 100644 --- a/tests/functional/arch/zx48k/read9.asm +++ b/tests/functional/arch/zx48k/read9.asm @@ -2363,6 +2363,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/readbug.asm b/tests/functional/arch/zx48k/readbug.asm index 2254415c6..99cf2a486 100644 --- a/tests/functional/arch/zx48k/readbug.asm +++ b/tests/functional/arch/zx48k/readbug.asm @@ -48,7 +48,7 @@ __DATA__0: __DATA__END: DEFB 00h ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code ;; Updates the DATA_ADDR read ptr for the next read @@ -66,7 +66,7 @@ __DATA__END: ;; 09: Float ;; bit7 is set for a parameter-less function ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm" ; Simple error control routines ; vim:ts=4:et: push namespace core @@ -100,9 +100,9 @@ __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" +#line 23 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -162,7 +162,7 @@ __STOP: ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -269,7 +269,7 @@ __MEM_INIT2: ret ENDP pop namespace -#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -300,9 +300,9 @@ __MEM_START: __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 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ret z ; NULL -#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; HL = Pointer to Free block ld e, (hl) inc hl @@ -367,7 +367,7 @@ __MEM_SUBTRACT: ret ENDP pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL @@ -404,8 +404,8 @@ __LOADSTR: ; __FASTCALL__ entry 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" +#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL @@ -423,8 +423,8 @@ __ILOAD32: 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" +#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL @@ -451,10 +451,10 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by 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" +#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" push namespace core __ABS32: bit 7, d @@ -479,7 +479,7 @@ __NEG32: ; Negates DEHL (Two's complement) inc de ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -551,7 +551,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -582,9 +582,9 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal 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" +#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" push namespace core __I8TOFREG: ld l, a @@ -654,7 +654,7 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" +#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -689,8 +689,8 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) 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" +#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -848,16 +848,16 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed 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" -#line 33 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 34 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 35 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 36 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; Updates restore point to the given HL mem. address push namespace core __RESTORE: @@ -1017,6 +1017,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' @@ -1137,5 +1144,5 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 23 "readbug.bas" +#line 23 "arch/zx48k/readbug.bas" END diff --git a/tests/functional/arch/zx48k/readokdown.asm b/tests/functional/arch/zx48k/readokdown.asm index bb26b2cba..98561df35 100644 --- a/tests/functional/arch/zx48k/readokdown.asm +++ b/tests/functional/arch/zx48k/readokdown.asm @@ -1466,7 +1466,7 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers pop namespace #line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printf16.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div16.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg16.asm" @@ -1485,7 +1485,7 @@ __NEGHL: inc hl ret pop namespace -#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/div16.asm" +#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div16.asm" push namespace core __DIVU16: ; 16 bit unsigned division ; HL = Dividend, Stack Top = Divisor @@ -1659,7 +1659,7 @@ __PRINT_FIX_LOOP: pop namespace #line 107 "arch/zx48k/readokdown.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi32.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div32.asm" ; --------------------------------------------------------- push namespace core __DIVU32: ; 32 bit unsigned division @@ -1808,7 +1808,7 @@ __PRINTU_LOOP: pop namespace #line 109 "arch/zx48k/readokdown.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div8.asm" ; -------------------------------- push namespace core __DIVU8: ; 8 bit unsigned integer division @@ -2550,6 +2550,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/readokup.asm b/tests/functional/arch/zx48k/readokup.asm index 5a4fe876f..2da02e334 100644 --- a/tests/functional/arch/zx48k/readokup.asm +++ b/tests/functional/arch/zx48k/readokup.asm @@ -1465,7 +1465,7 @@ __PRINT_MINUS: ; PRINT the MINUS (-) sign. CALLER must preserve registers pop namespace #line 2 "/zxbasic/src/lib/arch/zx48k/runtime/printf16.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi16.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div16.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div16.asm" ; 16 bit division and modulo functions ; for both signed and unsigned values #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg16.asm" @@ -1484,7 +1484,7 @@ __NEGHL: inc hl ret pop namespace -#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/div16.asm" +#line 5 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div16.asm" push namespace core __DIVU16: ; 16 bit unsigned division ; HL = Dividend, Stack Top = Divisor @@ -1658,7 +1658,7 @@ __PRINT_FIX_LOOP: pop namespace #line 106 "arch/zx48k/readokup.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi32.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div32.asm" ; --------------------------------------------------------- push namespace core __DIVU32: ; 32 bit unsigned division @@ -1807,7 +1807,7 @@ __PRINTU_LOOP: pop namespace #line 108 "arch/zx48k/readokup.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printi8.asm" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/div8.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/div8.asm" ; -------------------------------- push namespace core __DIVU8: ; 8 bit unsigned integer division @@ -2549,6 +2549,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' diff --git a/tests/functional/arch/zx48k/restore1.asm b/tests/functional/arch/zx48k/restore1.asm index f4115645d..9736d1379 100644 --- a/tests/functional/arch/zx48k/restore1.asm +++ b/tests/functional/arch/zx48k/restore1.asm @@ -55,7 +55,7 @@ _a: __DATA__END: DEFB 00h ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code ;; Updates the DATA_ADDR read ptr for the next read @@ -73,7 +73,7 @@ __DATA__END: ;; 09: Float ;; bit7 is set for a parameter-less function ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm" ; Simple error control routines ; vim:ts=4:et: push namespace core @@ -107,9 +107,9 @@ __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" +#line 23 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -169,7 +169,7 @@ __STOP: ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -276,7 +276,7 @@ __MEM_INIT2: ret ENDP pop namespace -#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -307,9 +307,9 @@ __MEM_START: __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 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ret z ; NULL -#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; HL = Pointer to Free block ld e, (hl) inc hl @@ -374,7 +374,7 @@ __MEM_SUBTRACT: ret ENDP pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL @@ -411,8 +411,8 @@ __LOADSTR: ; __FASTCALL__ entry 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" +#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL @@ -430,8 +430,8 @@ __ILOAD32: 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" +#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL @@ -458,10 +458,10 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by 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" +#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" push namespace core __ABS32: bit 7, d @@ -486,7 +486,7 @@ __NEG32: ; Negates DEHL (Two's complement) inc de ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -558,7 +558,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -589,9 +589,9 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal 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" +#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" push namespace core __I8TOFREG: ld l, a @@ -661,7 +661,7 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" +#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -696,8 +696,8 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) 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" +#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -855,16 +855,16 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed 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" -#line 33 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 34 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 35 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 36 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; Updates restore point to the given HL mem. address push namespace core __RESTORE: @@ -1024,6 +1024,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' @@ -1144,8 +1151,8 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 30 "restore1.bas" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" +#line 30 "arch/zx48k/restore1.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 @@ -1173,5 +1180,5 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 31 "restore1.bas" +#line 31 "arch/zx48k/restore1.bas" END diff --git a/tests/functional/arch/zx48k/restore3.asm b/tests/functional/arch/zx48k/restore3.asm index 954332a15..6c3b98364 100644 --- a/tests/functional/arch/zx48k/restore3.asm +++ b/tests/functional/arch/zx48k/restore3.asm @@ -53,7 +53,7 @@ _a: __DATA__END: DEFB 00h ;; --- end of user code --- -#line 1 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; This implements READ & RESTORE functions ;; Reads a new element from the DATA Address code ;; Updates the DATA_ADDR read ptr for the next read @@ -71,7 +71,7 @@ __DATA__END: ;; 09: Float ;; bit7 is set for a parameter-less function ;; In that case, the next two bytes are the ptr of the function to jump -#line 1 "/zxbasic/src/arch/zx48k/library-asm/error.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/error.asm" ; Simple error control routines ; vim:ts=4:et: push namespace core @@ -105,9 +105,9 @@ __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" +#line 23 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -167,7 +167,7 @@ __STOP: ; HL = BLOCK Start & DE = Length. ; An init directive is useful for initialization routines. ; They will be added automatically if needed. -#line 1 "/zxbasic/src/arch/zx48k/library-asm/heapinit.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/heapinit.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -274,7 +274,7 @@ __MEM_INIT2: ret ENDP pop namespace -#line 70 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 70 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; --------------------------------------------------------------------- ; MEM_ALLOC ; Allocates a block of memory in the heap. @@ -305,9 +305,9 @@ __MEM_START: __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 113 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 113 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ret z ; NULL -#line 115 "/zxbasic/src/arch/zx48k/library-asm/alloc.asm" +#line 115 "/zxbasic/src/lib/arch/zx48k/runtime/alloc.asm" ; HL = Pointer to Free block ld e, (hl) inc hl @@ -372,7 +372,7 @@ __MEM_SUBTRACT: ret ENDP pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/loadstr.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/loadstr.asm" ; Loads a string (ptr) from HL ; and duplicates it on dynamic memory again ; Finally, it returns result pointer in HL @@ -409,8 +409,8 @@ __LOADSTR: ; __FASTCALL__ entry 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" +#line 24 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iload32.asm" ; __FASTCALL__ routine which ; loads a 32 bits integer into DE,HL ; stored at position pointed by POINTER HL @@ -428,8 +428,8 @@ __ILOAD32: 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" +#line 25 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/iloadf.asm" ; __FASTCALL__ routine which ; loads a 40 bits floating point into A ED CB ; stored at position pointed by POINTER HL @@ -456,10 +456,10 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by 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" +#line 26 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftof16reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ftou32reg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" push namespace core __ABS32: bit 7, d @@ -484,7 +484,7 @@ __NEG32: ; Negates DEHL (Two's complement) inc de ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftou32reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -556,7 +556,7 @@ __FTOU8: ; Converts float in C ED LH to Unsigned byte in A ld a, l ret pop namespace -#line 2 "/zxbasic/src/arch/zx48k/library-asm/ftof16reg.asm" +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -587,9 +587,9 @@ __FTOF16REG: ; Converts a Float to 16.16 (32 bit) fixed point decimal 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" +#line 27 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/f16tofreg.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" push namespace core __I8TOFREG: ld l, a @@ -659,7 +659,7 @@ __U32TOFREG_END: ret ENDP pop namespace -#line 3 "/zxbasic/src/arch/zx48k/library-asm/f16tofreg.asm" +#line 3 "/zxbasic/src/lib/arch/zx48k/runtime/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) @@ -694,8 +694,8 @@ __F16TOFREG2: ; Converts an unsigned 32 bit integer (DEHL) 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" +#line 28 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/free.asm" ; vim: ts=4:et:sw=4: ; Copyleft (K) by Jose M. Rodriguez de la Rosa ; (a.k.a. Boriel) @@ -853,16 +853,16 @@ __MEM_BLOCK_JOIN: ; Joins current block (pointed by HL) with next one (pointed 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" -#line 33 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 34 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 35 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 36 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 37 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 38 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" -#line 39 "/zxbasic/src/arch/zx48k/library-asm/read_restore.asm" +#line 29 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 31 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 32 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 33 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 34 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 35 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 36 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 37 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 38 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" +#line 39 "/zxbasic/src/lib/arch/zx48k/runtime/read_restore.asm" ;; Updates restore point to the given HL mem. address push namespace core __RESTORE: @@ -1022,6 +1022,13 @@ _from_u16: jp _from_i32 dynamic_cast4: ;; The user type is "shorter" than the read one + ld a, b ;; read type + cp 4 ;; if user type < read type < _i16 => From Ubyte to Byte. Return af' + jr nc, 1f + ex af, af' + ret +1: + ld a, c ;; recover user required type cp 8 ;; required type jr c, before_to_int ;; required < fixed (f16) ex af, af' @@ -1142,8 +1149,8 @@ __DATA_ADDR: ;; Stores current DATA ptr dw .DATA.__DATA__0 ENDP pop namespace -#line 28 "restore3.bas" -#line 1 "/zxbasic/src/arch/zx48k/library-asm/storef.asm" +#line 28 "arch/zx48k/restore3.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/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 @@ -1171,5 +1178,5 @@ __STOREF: ; Stores the given FP number in A EDCB at address HL ld (hl), b ret pop namespace -#line 29 "restore3.bas" +#line 29 "arch/zx48k/restore3.bas" END diff --git a/tests/functional/arch/zx48k/read13.bas b/tests/runtime/cases/read_float_expr_into_fixed.bas similarity index 56% rename from tests/functional/arch/zx48k/read13.bas rename to tests/runtime/cases/read_float_expr_into_fixed.bas index 4c0427c59..5757bbb8f 100644 --- a/tests/functional/arch/zx48k/read13.bas +++ b/tests/runtime/cases/read_float_expr_into_fixed.bas @@ -1,16 +1,21 @@ -REM Error x is an array, not an scalar +#include "lib/tst_framework.bas" DIM v as Fixed = 1.5 RESTORE -DATA 10, 25 * v, SIN(v) * tan(v)^2, PI * v +INIT("Test read FP into Fixed") -DIM i as UByte +DATA 10, 25 * v, SIN(v) * tan(v)^2, PI * v + +DIM i as UByte DIM c(3) as Fixed + FOR i = 0 TO 3: -READ c(i) -PRINT c(i) + READ c(i) + PRINT c(i) NEXT i + +REPORT_OK diff --git a/tests/runtime/expected/read_float_expr_into_fixed.tzx.scr b/tests/runtime/expected/read_float_expr_into_fixed.tzx.scr new file mode 100644 index 000000000..18fa8f23e Binary files /dev/null and b/tests/runtime/expected/read_float_expr_into_fixed.tzx.scr differ